@maptalks/traffic 0.97.4 → 0.98.0
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/dist/maptalks.traffic.d.ts +492 -0
- package/dist/maptalks.traffic.es.js +471 -533
- package/dist/maptalks.traffic.es.js.map +1 -0
- package/dist/maptalks.traffic.js +3 -2
- package/dist/maptalks.traffic.js.map +1 -0
- package/package.json +34 -27
|
@@ -1,142 +1,32 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @maptalks/traffic v0.
|
|
2
|
+
* @maptalks/traffic v0.98.0
|
|
3
3
|
* LICENSE : UNLICENSED
|
|
4
4
|
* (c) 2016-2024 maptalks.org
|
|
5
5
|
*/
|
|
6
6
|
import * as t from "maptalks";
|
|
7
7
|
|
|
8
|
-
import
|
|
8
|
+
import * as s from "@turf/turf";
|
|
9
9
|
|
|
10
|
-
import
|
|
10
|
+
import { GLTFLayer as i, MultiGLTFMarker as h } from "@maptalks/gltf-layer";
|
|
11
11
|
|
|
12
|
-
let
|
|
12
|
+
let n = 0;
|
|
13
13
|
|
|
14
|
-
function
|
|
15
|
-
return
|
|
16
|
-
const i = function(t) {
|
|
17
|
-
if (!function(t) {
|
|
18
|
-
return t === Object(t);
|
|
19
|
-
}(t)) return [];
|
|
20
|
-
const i = [];
|
|
21
|
-
for (const s in t) a(t, s) && i.push(s);
|
|
22
|
-
return i;
|
|
23
|
-
}(t), s = i.length, n = new Array(s);
|
|
24
|
-
for (let e = 0; e < s; e++) n[e] = t[i[e]];
|
|
25
|
-
return n;
|
|
26
|
-
}(t)), t[u(t.length - 1)]) : function(t) {
|
|
27
|
-
let i, s = 0;
|
|
28
|
-
const n = [];
|
|
29
|
-
return c(t, t => {
|
|
30
|
-
i = i(s++), n[s - 1] = n[i], n[i] = t;
|
|
31
|
-
}), n;
|
|
32
|
-
}(t).slice(0, Math.max(0, i));
|
|
14
|
+
function e(t, s, i) {
|
|
15
|
+
return t.length !== +t.length && (t = Object.values(t)), t[o(t.length - 1)];
|
|
33
16
|
}
|
|
34
17
|
|
|
35
|
-
function
|
|
36
|
-
const
|
|
37
|
-
return t ? t +
|
|
18
|
+
function r(t) {
|
|
19
|
+
const s = ++n + "";
|
|
20
|
+
return t ? t + s : s;
|
|
38
21
|
}
|
|
39
22
|
|
|
40
|
-
function o(t,
|
|
41
|
-
|
|
42
|
-
if (nativeBind && t.bind === nativeBind) return nativeBind.apply(t, slice.call(arguments, 1));
|
|
43
|
-
const n = slice.call(arguments, 2);
|
|
44
|
-
return s = function() {
|
|
45
|
-
if (!(this instanceof s)) return t.apply(i, n.concat(slice.call(arguments)));
|
|
46
|
-
ctor.prototype = t.prototype;
|
|
47
|
-
const e = new ctor;
|
|
48
|
-
ctor.prototype = null;
|
|
49
|
-
const r = t.apply(e, n.concat(slice.call(arguments)));
|
|
50
|
-
return Object(r) === r ? r : e;
|
|
51
|
-
};
|
|
23
|
+
function o(t, s) {
|
|
24
|
+
return s || (s = t, t = 0), t + Math.floor(Math.random() * (s - t + 1));
|
|
52
25
|
}
|
|
53
26
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
function l(t) {
|
|
59
|
-
return c(slice.call(arguments, 1), (function(i) {
|
|
60
|
-
if (i) for (const s in i) t[s] = i[s];
|
|
61
|
-
})), t;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function c(t, i, s) {
|
|
65
|
-
if (null == t) return t;
|
|
66
|
-
if (nativeForEach && t.forEach === nativeForEach) t.forEach(i, s); else if (t.length === +t.length) {
|
|
67
|
-
for (let n = 0, e = t.length; n < e; n++) if (i.call(s, t[n], n, t) === breaker) return null;
|
|
68
|
-
} else {
|
|
69
|
-
const n = n(t);
|
|
70
|
-
for (let e = 0, r = n.length; e < r; e++) if (i.call(s, t[n[e]], n[e], t) === breaker) return null;
|
|
71
|
-
}
|
|
72
|
-
return t;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function a(t, i) {
|
|
76
|
-
return hasOwnProperty.call(t, i);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
class f {
|
|
80
|
-
constructor(t, i) {
|
|
81
|
-
let s, n, e;
|
|
82
|
-
if (this.factory = t, this.objects = {}, null != i && null != i.objects) for (s in e = i.objects,
|
|
83
|
-
e) n = e[s], this.objects[s] = this.factory.copy(n);
|
|
84
|
-
}
|
|
85
|
-
get length() {
|
|
86
|
-
return Object.keys(this.objects).length;
|
|
87
|
-
}
|
|
88
|
-
toJSON() {
|
|
89
|
-
return this.objects;
|
|
90
|
-
}
|
|
91
|
-
get(t) {
|
|
92
|
-
return this.objects[t];
|
|
93
|
-
}
|
|
94
|
-
put(t) {
|
|
95
|
-
return this.objects[t.id] = t;
|
|
96
|
-
}
|
|
97
|
-
pop(t) {
|
|
98
|
-
let i;
|
|
99
|
-
const s = null != (i = t.id) ? i : t, n = this.objects[s];
|
|
100
|
-
return "function" == typeof n.release && n.release(), delete this.objects[s], n;
|
|
101
|
-
}
|
|
102
|
-
all() {
|
|
103
|
-
return this.objects;
|
|
104
|
-
}
|
|
105
|
-
clear() {
|
|
106
|
-
return this.objects = {};
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
class d {
|
|
111
|
-
constructor(t, i) {
|
|
112
|
-
this.x = t || 0, this.y = i || 0;
|
|
113
|
-
}
|
|
114
|
-
get length() {
|
|
115
|
-
return Math.sqrt(this.x * this.x + this.y * this.y);
|
|
116
|
-
}
|
|
117
|
-
get direction() {
|
|
118
|
-
return Math.atan2(this.y, this.x);
|
|
119
|
-
}
|
|
120
|
-
get normalized() {
|
|
121
|
-
return new d(this.x / this.length, this.y / this.length);
|
|
122
|
-
}
|
|
123
|
-
add(t) {
|
|
124
|
-
return new d(this.x + t.x, this.y + t.y);
|
|
125
|
-
}
|
|
126
|
-
subtract(t) {
|
|
127
|
-
return new d(this.x - t.x, this.y - t.y);
|
|
128
|
-
}
|
|
129
|
-
mult(t) {
|
|
130
|
-
return new d(this.x * t, this.y * t);
|
|
131
|
-
}
|
|
132
|
-
divide(t) {
|
|
133
|
-
return new d(this.x / t, this.y / t);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
class g {
|
|
138
|
-
constructor(t, i) {
|
|
139
|
-
this.source = t, this.target = i;
|
|
27
|
+
class u {
|
|
28
|
+
constructor(t, s) {
|
|
29
|
+
this.source = t, this.target = s;
|
|
140
30
|
}
|
|
141
31
|
get vector() {
|
|
142
32
|
return this.target.subtract(this.source);
|
|
@@ -150,148 +40,53 @@ class g {
|
|
|
150
40
|
get center() {
|
|
151
41
|
return this.getPoint(.5);
|
|
152
42
|
}
|
|
153
|
-
split(t,
|
|
154
|
-
let
|
|
155
|
-
const u =
|
|
156
|
-
|
|
157
|
-
for (let
|
|
158
|
-
return
|
|
43
|
+
split(t, s) {
|
|
44
|
+
let i, h, n, e, r, o;
|
|
45
|
+
const u = s ? function() {
|
|
46
|
+
r = [];
|
|
47
|
+
for (let s = e = t - 1; e <= 0 ? s <= 0 : s >= 0; e <= 0 ? s++ : s--) r.push(s);
|
|
48
|
+
return r;
|
|
159
49
|
}.apply(this) : function() {
|
|
160
50
|
o = [];
|
|
161
|
-
for (let
|
|
51
|
+
for (let s = 0, i = t - 1; 0 <= i ? s <= i : s >= i; 0 <= i ? s++ : s--) o.push(s);
|
|
162
52
|
return o;
|
|
163
53
|
}.apply(this), l = [];
|
|
164
|
-
for (
|
|
54
|
+
for (h = 0, n = u.length; h < n; h++) i = u[h], l.push(this.subsegment(i / t, (i + 1) / t));
|
|
165
55
|
return l;
|
|
166
56
|
}
|
|
167
57
|
getPoint(t) {
|
|
168
58
|
return this.source.add(this.vector.mult(t));
|
|
169
59
|
}
|
|
170
|
-
subsegment(t,
|
|
171
|
-
const
|
|
172
|
-
return new
|
|
60
|
+
subsegment(t, s) {
|
|
61
|
+
const i = this.vector, h = this.source.add(i.mult(t)), n = this.source.add(i.mult(s));
|
|
62
|
+
return new u(h, n);
|
|
173
63
|
}
|
|
174
64
|
}
|
|
175
65
|
|
|
176
|
-
class
|
|
177
|
-
constructor(t,
|
|
178
|
-
this.
|
|
179
|
-
|
|
180
|
-
copy(t) {
|
|
181
|
-
return new w(t.x, t.y, t.width, t.height);
|
|
182
|
-
}
|
|
183
|
-
toJSON() {
|
|
184
|
-
return l({}, this);
|
|
185
|
-
}
|
|
186
|
-
area() {
|
|
187
|
-
return this.width * this.height;
|
|
188
|
-
}
|
|
189
|
-
left(t) {
|
|
190
|
-
return null != t && (this.x = t), this.x;
|
|
191
|
-
}
|
|
192
|
-
right(t) {
|
|
193
|
-
return null != t && (this.x = t - this.width), this.x + this.width;
|
|
194
|
-
}
|
|
195
|
-
top(t) {
|
|
196
|
-
return null != t && (this.y = t), this.y;
|
|
66
|
+
class l {
|
|
67
|
+
constructor(t, s, i, h) {
|
|
68
|
+
this.A = t, this.B = s, this.O = i, this.Q = h, this.AO = new u(this.A, this.O),
|
|
69
|
+
this.OQ = new u(this.O, this.Q), this.QB = new u(this.Q, this.B), this.len = null;
|
|
197
70
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
return
|
|
203
|
-
new d(this.x + this.width / 2, this.y + this.heigh / 2);
|
|
204
|
-
}
|
|
205
|
-
containsPoint(t) {
|
|
206
|
-
let i, s;
|
|
207
|
-
return this.left() <= (i = t.x) && i <= this.right() && this.top() <= (s = t.y) && s <= this.bottom();
|
|
208
|
-
}
|
|
209
|
-
containsRect(t) {
|
|
210
|
-
return this.left() <= t.left() && t.right() <= this.right() && this.top() <= t.top() && t.bottom() <= this.bottom();
|
|
211
|
-
}
|
|
212
|
-
getVertices() {
|
|
213
|
-
return [ new d(this.left(), this.top()), new d(this.right(), this.top()), new d(this.right(), this.bottom()), new d(this.left(), this.bottom()) ];
|
|
214
|
-
}
|
|
215
|
-
getSide(t) {
|
|
216
|
-
const i = this.getVertices();
|
|
217
|
-
return new g(i[t], i[(t + 1) % 4]);
|
|
218
|
-
}
|
|
219
|
-
getSectorId(t) {
|
|
220
|
-
const i = t.subtract(this.center());
|
|
221
|
-
if (i.y <= 0 && Math.abs(i.x) <= Math.abs(i.y)) return 0;
|
|
222
|
-
if (i.x >= 0 && Math.abs(i.x) >= Math.abs(i.y)) return 1;
|
|
223
|
-
if (i.y >= 0 && Math.abs(i.x) <= Math.abs(i.y)) return 2;
|
|
224
|
-
if (i.x <= 0 && Math.abs(i.x) >= Math.abs(i.y)) return 3;
|
|
225
|
-
throw new Error("algorithm error");
|
|
226
|
-
}
|
|
227
|
-
getSector(t) {
|
|
228
|
-
return this.getSide(this.getSectorId(t));
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
class p {
|
|
233
|
-
constructor(t) {
|
|
234
|
-
this.intersection = t, this.time = 0, this.flipMultiplier = .4 * Math.random() - .2 + 1,
|
|
235
|
-
this.stateNum = 0, this.lightsFlipInterval = 20, this.states = [ [ "L", "", "L", "" ], [ "FR", "", "FR", "" ], [ "", "L", "", "L" ], [ "", "FR", "", "FR" ] ];
|
|
236
|
-
}
|
|
237
|
-
get flipInterval() {
|
|
238
|
-
return this.flipMultiplier * this.lightsFlipInterval;
|
|
239
|
-
}
|
|
240
|
-
get state() {
|
|
241
|
-
let t = this.states[this.stateNum % this.states.length];
|
|
242
|
-
this.intersection.roads.length <= 2 && (t = [ "LFR", "LFR", "LFR", "LFR" ]);
|
|
243
|
-
const i = [];
|
|
244
|
-
for (let s = 0, n = t.length; s < n; s++) {
|
|
245
|
-
const n = t[s];
|
|
246
|
-
i.push(this.decode(n));
|
|
247
|
-
}
|
|
248
|
-
return i;
|
|
249
|
-
}
|
|
250
|
-
decode(t) {
|
|
251
|
-
const i = [ 0, 0, 0 ], s = [].indexOf || function(t) {
|
|
252
|
-
for (let i = 0, s = this.length; i < s; i++) if (i in this && this[i] === t) return i;
|
|
253
|
-
return -1;
|
|
254
|
-
};
|
|
255
|
-
return s.call(t, "L") >= 0 && (i[0] = 1), s.call(t, "F") >= 0 && (i[1] = 1), s.call(t, "R") >= 0 && (i[2] = 1),
|
|
256
|
-
i;
|
|
257
|
-
}
|
|
258
|
-
flip() {
|
|
259
|
-
return this.stateNum += 1;
|
|
260
|
-
}
|
|
261
|
-
onTick(t) {
|
|
262
|
-
return this.time += t, this.time > this.flipInterval ? (this.flip(), this.time -= this.flipInterval) : null;
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
class m {
|
|
267
|
-
constructor(t) {
|
|
268
|
-
this.rect = t, this.id = h("intersection"), this.roads = [], this.inRoads = [],
|
|
269
|
-
this.controlSignals = new p(this);
|
|
270
|
-
}
|
|
271
|
-
copy(t) {
|
|
272
|
-
t.rect = w.copy(t.rect);
|
|
273
|
-
const i = Object.create(m.prototype);
|
|
274
|
-
return l(i, t), i.roads = [], i.inRoads = [], i.controlSignals = new p(i), i;
|
|
71
|
+
get length() {
|
|
72
|
+
let t, s, i, h, n;
|
|
73
|
+
if (null == this.len) for (i = 10, h = null, this.len = 0, t = n = 0; n <= 10; t = ++n) s = this.getPoint(t / 10),
|
|
74
|
+
h && (this.len += s.subtract(h).length), h = s;
|
|
75
|
+
return this.len;
|
|
275
76
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
rect: this.rect
|
|
280
|
-
};
|
|
77
|
+
getPoint(t) {
|
|
78
|
+
const s = this.AO.getPoint(t), i = this.OQ.getPoint(t), h = this.QB.getPoint(t), n = new u(s, i).getPoint(t), e = new u(i, h).getPoint(t);
|
|
79
|
+
return new u(n, e).getPoint(t);
|
|
281
80
|
}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
for (i = 0, n = r.length; i < n; i++) t = r[i], t.update();
|
|
286
|
-
const h = this.inRoads, o = [];
|
|
287
|
-
for (s = 0, e = h.length; s < e; s++) t = h[s], o.push(t.update());
|
|
288
|
-
return o;
|
|
81
|
+
getDirection(t) {
|
|
82
|
+
const s = this.AO.getPoint(t), i = this.OQ.getPoint(t), h = this.QB.getPoint(t), n = new u(s, i).getPoint(t), e = new u(i, h).getPoint(t);
|
|
83
|
+
return new u(n, e).direction;
|
|
289
84
|
}
|
|
290
85
|
}
|
|
291
86
|
|
|
292
|
-
class
|
|
293
|
-
constructor(t,
|
|
294
|
-
this.
|
|
87
|
+
class c {
|
|
88
|
+
constructor(t, s, i) {
|
|
89
|
+
this.id = r("laneposition"), this.free = !0, this.car = t, this.position = i, this.tmpLane = s;
|
|
295
90
|
}
|
|
296
91
|
get lane() {
|
|
297
92
|
return this.tmpLane;
|
|
@@ -303,12 +98,12 @@ class v {
|
|
|
303
98
|
return this.position / this.lane.length;
|
|
304
99
|
}
|
|
305
100
|
get nextCarDistance() {
|
|
306
|
-
let t,
|
|
307
|
-
const
|
|
308
|
-
return
|
|
101
|
+
let t, s;
|
|
102
|
+
const i = this.getNext();
|
|
103
|
+
return i ? (s = i.position - i.car.length / 2, t = this.position + this.car.length / 2,
|
|
309
104
|
{
|
|
310
|
-
car:
|
|
311
|
-
distance:
|
|
105
|
+
car: i.car,
|
|
106
|
+
distance: s - t
|
|
312
107
|
}) : {
|
|
313
108
|
car: null,
|
|
314
109
|
distance: 1 / 0
|
|
@@ -329,51 +124,29 @@ class v {
|
|
|
329
124
|
}
|
|
330
125
|
}
|
|
331
126
|
|
|
332
|
-
class
|
|
333
|
-
constructor(t,
|
|
334
|
-
this.
|
|
335
|
-
this.
|
|
336
|
-
this.len = null;
|
|
337
|
-
}
|
|
338
|
-
get length() {
|
|
339
|
-
let t, i, s, n, e;
|
|
340
|
-
if (null == this.len) for (s = 10, n = null, this.len = 0, t = e = 0; e <= 10; t = ++e) i = this.getPoint(t / 10),
|
|
341
|
-
n && (this.len += i.subtract(n).length), n = i;
|
|
342
|
-
return this.len;
|
|
343
|
-
}
|
|
344
|
-
getPoint(t) {
|
|
345
|
-
const i = this.AO.getPoint(t), s = this.OQ.getPoint(t), n = this.QB.getPoint(t), e = new g(i, s).getPoint(t), r = new g(s, n).getPoint(t);
|
|
346
|
-
return new g(e, r).getPoint(t);
|
|
347
|
-
}
|
|
348
|
-
getDirection(t) {
|
|
349
|
-
const i = this.AO.getPoint(t), s = this.OQ.getPoint(t), n = this.QB.getPoint(t), e = new g(i, s).getPoint(t), r = new g(s, n).getPoint(t);
|
|
350
|
-
return new g(e, r).direction;
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
class y {
|
|
355
|
-
constructor(t, i, s) {
|
|
356
|
-
this.car = t, this.current = new v(this.car, i, s || 0), this.current.acquire(),
|
|
357
|
-
this.next = new v(this.car), this.temp = new v(this.car), this.isChangingLanes = !1;
|
|
127
|
+
class a {
|
|
128
|
+
constructor(t, s, i) {
|
|
129
|
+
this.isChangingLanes = !1, this.car = t, this.current = new c(t, s, i || 0), this.current.acquire(),
|
|
130
|
+
this.next = new c(t), this.temp = new c(t);
|
|
358
131
|
}
|
|
359
132
|
get lane() {
|
|
360
133
|
return this.temp.lane || this.current.lane;
|
|
361
134
|
}
|
|
362
135
|
get absolutePosition() {
|
|
363
|
-
return null
|
|
136
|
+
return null !== this.temp.lane && void 0 !== this.temp.lane ? this.temp.position : this.current.position;
|
|
364
137
|
}
|
|
365
138
|
get relativePosition() {
|
|
366
139
|
return this.absolutePosition / this.lane.length;
|
|
367
140
|
}
|
|
368
141
|
get direction() {
|
|
369
|
-
return this.lane.getDirection(
|
|
142
|
+
return this.lane.getDirection();
|
|
370
143
|
}
|
|
371
144
|
get coords() {
|
|
372
145
|
return this.lane.getPoint(this.relativePosition);
|
|
373
146
|
}
|
|
374
147
|
get nextCarDistance() {
|
|
375
|
-
const t = this.current.nextCarDistance,
|
|
376
|
-
return t.distance <
|
|
148
|
+
const t = this.current.nextCarDistance, s = this.next.nextCarDistance;
|
|
149
|
+
return t.distance < s.distance ? t : s;
|
|
377
150
|
}
|
|
378
151
|
get distanceToStopLine() {
|
|
379
152
|
return this.canEnterIntersection() ? 1 / 0 : this.getDistanceToIntersection();
|
|
@@ -385,55 +158,55 @@ class y {
|
|
|
385
158
|
return this.current.lane.road.source;
|
|
386
159
|
}
|
|
387
160
|
isValidTurn() {
|
|
388
|
-
const t = this.car.nextLane,
|
|
389
|
-
if (3 ===
|
|
390
|
-
if (0 ===
|
|
391
|
-
if (2 ===
|
|
161
|
+
const t = this.car.nextLane, s = this.current.lane, i = s.getTurnDirection(t);
|
|
162
|
+
if (3 === i) throw Error("no U-turns are allowed");
|
|
163
|
+
if (0 === i && !s.isLeftmost) throw Error("no left turns from this lane");
|
|
164
|
+
if (2 === i && !s.isRightmost) throw Error("no right turns from this lane");
|
|
392
165
|
return !0;
|
|
393
166
|
}
|
|
394
167
|
canEnterIntersection() {
|
|
395
|
-
const t = this.car.nextLane,
|
|
168
|
+
const t = this.car.nextLane, s = this.current.lane;
|
|
396
169
|
if (!t) return !0;
|
|
397
|
-
const
|
|
398
|
-
return
|
|
170
|
+
const i = this.nextIntersection, h = s.getTurnDirection(t), n = s.road.targetSideId;
|
|
171
|
+
return i.controlSignals.state[n][h];
|
|
399
172
|
}
|
|
400
173
|
getDistanceToIntersection() {
|
|
401
174
|
const t = this.current.lane.length - this.car.length / 2 - this.current.position;
|
|
402
175
|
return this.isChangingLanes ? 1 / 0 : Math.max(t, 0);
|
|
403
176
|
}
|
|
404
177
|
timeToMakeTurn(t) {
|
|
405
|
-
return
|
|
178
|
+
return void 0 === t && (t = 0), this.getDistanceToIntersection() <= t;
|
|
406
179
|
}
|
|
407
180
|
moveForward(t) {
|
|
408
|
-
let
|
|
181
|
+
let s, i;
|
|
409
182
|
t = Math.max(t, 0), this.current.position += t, this.next.position += t, this.temp.position += t,
|
|
410
183
|
this.timeToMakeTurn() && this.canEnterIntersection() && this.isValidTurn() && this.t(this.car.popNextLane(), 0);
|
|
411
|
-
const
|
|
412
|
-
return this.isChangingLanes && this.temp.position >
|
|
413
|
-
this.isChangingLanes && this.next.free && this.temp.position +
|
|
414
|
-
this.isChangingLanes &&
|
|
184
|
+
const h = this.temp.position / (null != (s = this.temp.lane) ? s.length : void 0), n = 2 * this.car.length;
|
|
185
|
+
return this.isChangingLanes && this.temp.position > n && !this.current.free && this.current.release(),
|
|
186
|
+
this.isChangingLanes && this.next.free && this.temp.position + n > (null != (i = this.temp.lane) ? i.length : void 0) && this.next.acquire(),
|
|
187
|
+
this.isChangingLanes && h >= 1 && this.i(), !this.current.lane || this.isChangingLanes || this.car.nextLane ? null : this.car.pickNextLane();
|
|
415
188
|
}
|
|
416
189
|
changeLane(t) {
|
|
417
190
|
if (this.isChangingLanes) throw Error("already changing lane");
|
|
418
191
|
if (null == t) throw Error("no next lane");
|
|
419
192
|
if (t === this.lane) throw Error("next lane == current lane");
|
|
420
193
|
if (this.lane.road !== t.road) throw Error("not neighbouring lanes");
|
|
421
|
-
const
|
|
422
|
-
return this.t(t,
|
|
423
|
-
}
|
|
424
|
-
s() {
|
|
425
|
-
const t = this.current.lane.getPoint(this.current.relativePosition), i = this.next.lane.getPoint(this.next.relativePosition), s = i.subtract(t).length, n = this.current.lane.middleLine.vector.normalized.mult(.3 * s), e = t.add(n), r = this.next.lane.middleLine.vector.normalized.mult(.3 * s), h = i.subtract(r);
|
|
426
|
-
return new M(t, i, e, h);
|
|
194
|
+
const s = this.current.position + 3 * this.car.length;
|
|
195
|
+
return this.t(t, s);
|
|
427
196
|
}
|
|
428
197
|
h() {
|
|
429
|
-
|
|
198
|
+
const t = this.current.lane.getPoint(this.current.relativePosition), s = this.next.lane.getPoint(this.next.relativePosition), i = s.subtract(t).length, h = this.current.lane.middleLine.vector.normalized.mult(.3 * i), n = t.add(h), e = this.next.lane.middleLine.vector.normalized.mult(.3 * i), r = s.subtract(e);
|
|
199
|
+
return new l(t, s, n, r);
|
|
430
200
|
}
|
|
431
|
-
|
|
201
|
+
o() {
|
|
202
|
+
return this.h();
|
|
203
|
+
}
|
|
204
|
+
t(t, s) {
|
|
432
205
|
if (this.isChangingLanes) throw Error("already changing lane");
|
|
433
206
|
if (null == t) return 0;
|
|
434
|
-
this.isChangingLanes = !0, this.next.lane = t, this.next.position =
|
|
435
|
-
const
|
|
436
|
-
return this.temp.lane =
|
|
207
|
+
this.isChangingLanes = !0, this.next.lane = t, this.next.position = s;
|
|
208
|
+
const i = this.o();
|
|
209
|
+
return this.temp.lane = i, this.temp.position = 0, this.next.position -= this.temp.lane.length;
|
|
437
210
|
}
|
|
438
211
|
i() {
|
|
439
212
|
if (!this.isChangingLanes) throw Error("no lane changing is going on");
|
|
@@ -442,20 +215,20 @@ class y {
|
|
|
442
215
|
this.temp.position = NaN, this.current.lane;
|
|
443
216
|
}
|
|
444
217
|
release() {
|
|
445
|
-
let t,
|
|
446
|
-
return null != (t = this.current) && t.release(), null != (
|
|
447
|
-
null != (
|
|
218
|
+
let t, s, i;
|
|
219
|
+
return null != (t = this.current) && t.release(), null != (s = this.next) && s.release(),
|
|
220
|
+
null != (i = this.temp) ? i.release() : void 0;
|
|
448
221
|
}
|
|
449
222
|
}
|
|
450
223
|
|
|
451
|
-
const
|
|
224
|
+
const f = [];
|
|
452
225
|
|
|
453
|
-
class
|
|
454
|
-
constructor(t,
|
|
455
|
-
this.type =
|
|
456
|
-
this.
|
|
457
|
-
this.timeHeadway = 1.5, this.maxAcceleration = 1, this.maxDeceleration = 3,
|
|
458
|
-
this.alive = !0, this.
|
|
226
|
+
class d {
|
|
227
|
+
constructor(t, s) {
|
|
228
|
+
this.type = o(f.length - 1), this.id = r("car"), this.color = (300 + 240 * Math.random() | 0) % 360,
|
|
229
|
+
this.preferedLane = null, this.width = 2, this.length = 2, this.tmpSpeed = 0, this.maxSpeed = 30,
|
|
230
|
+
this.s0 = 2, this.timeHeadway = 1.5, this.maxAcceleration = 1, this.maxDeceleration = 3,
|
|
231
|
+
this.alive = !0, this.trajectory = new a(this, t, s);
|
|
459
232
|
}
|
|
460
233
|
get coords() {
|
|
461
234
|
return this.trajectory.coords;
|
|
@@ -474,14 +247,14 @@ class C {
|
|
|
474
247
|
}
|
|
475
248
|
getAcceleration() {
|
|
476
249
|
let t;
|
|
477
|
-
const
|
|
250
|
+
const s = this.trajectory.nextCarDistance, i = Math.max(s.distance, 0), h = this.maxAcceleration, n = this.maxDeceleration, e = this.speed - (null != (t = s.car) ? t.speed : void 0) || 0, r = Math.pow(this.speed / this.maxSpeed, 4), o = this.s0, u = this.speed * this.timeHeadway, l = o + u + this.speed * e / (2 * Math.sqrt(h * n)), c = Math.pow(l / i, 2), a = 1 + u + Math.pow(this.speed, 2) / (2 * n), f = 1 - r - c - Math.pow(a / this.trajectory.distanceToStopLine, 2);
|
|
478
251
|
return this.maxAcceleration * f;
|
|
479
252
|
}
|
|
480
253
|
move(t) {
|
|
481
|
-
const
|
|
482
|
-
if (this.speed +=
|
|
483
|
-
const t = this.trajectory.current.lane,
|
|
484
|
-
switch (
|
|
254
|
+
const s = this.getAcceleration();
|
|
255
|
+
if (this.speed += s * t, !this.trajectory.isChangingLanes && this.nextLane) {
|
|
256
|
+
const t = this.trajectory.current.lane, s = t.getTurnDirection(this.nextLane), i = function() {
|
|
257
|
+
switch (s) {
|
|
485
258
|
case 0:
|
|
486
259
|
return t.leftmostAdjacent;
|
|
487
260
|
|
|
@@ -492,38 +265,38 @@ class C {
|
|
|
492
265
|
return t;
|
|
493
266
|
}
|
|
494
267
|
}();
|
|
495
|
-
|
|
268
|
+
i !== t && this.trajectory.changeLane(i);
|
|
496
269
|
}
|
|
497
|
-
const
|
|
498
|
-
return this.trajectory.nextCarDistance.distance <
|
|
499
|
-
this.alive) : this.trajectory.moveForward(
|
|
270
|
+
const i = this.speed * t + .5 * s * Math.pow(t, 2);
|
|
271
|
+
return this.trajectory.nextCarDistance.distance < i && console.log("bad IDM"), this.trajectory.timeToMakeTurn(i) && null == this.nextLane ? (this.alive = !1,
|
|
272
|
+
this.alive) : this.trajectory.moveForward(i);
|
|
500
273
|
}
|
|
501
274
|
pickNextRoad() {
|
|
502
|
-
const t = this.trajectory.nextIntersection,
|
|
503
|
-
return t.target !==
|
|
275
|
+
const t = this.trajectory.nextIntersection, s = this.trajectory.current.lane, i = t.roads.filter((function(t) {
|
|
276
|
+
return t.target !== s.road.source;
|
|
504
277
|
}));
|
|
505
|
-
if (0 ===
|
|
506
|
-
return
|
|
278
|
+
if (0 === i.length) return null;
|
|
279
|
+
return e(i);
|
|
507
280
|
}
|
|
508
281
|
pickNextLane() {
|
|
509
282
|
if (this.nextLane) throw Error("next lane is already chosen");
|
|
510
283
|
this.nextLane = null;
|
|
511
284
|
const t = this.pickNextRoad();
|
|
512
285
|
if (!t) return null;
|
|
513
|
-
const
|
|
514
|
-
switch (
|
|
286
|
+
const s = this.trajectory.current.lane.road.getTurnDirection(t), i = function() {
|
|
287
|
+
switch (s) {
|
|
515
288
|
case 0:
|
|
516
289
|
return t.lanesNumber - 1;
|
|
517
290
|
|
|
518
291
|
case 1:
|
|
519
|
-
return
|
|
292
|
+
return o(0, t.lanesNumber - 1);
|
|
520
293
|
|
|
521
294
|
case 2:
|
|
522
295
|
return 0;
|
|
523
296
|
}
|
|
524
297
|
return null;
|
|
525
298
|
}();
|
|
526
|
-
return this.nextLane = t.lanes[
|
|
299
|
+
return this.nextLane = t.lanes[i], this.nextLane;
|
|
527
300
|
}
|
|
528
301
|
popNextLane() {
|
|
529
302
|
const t = this.nextLane;
|
|
@@ -531,11 +304,187 @@ class C {
|
|
|
531
304
|
}
|
|
532
305
|
}
|
|
533
306
|
|
|
534
|
-
class
|
|
535
|
-
constructor(t
|
|
536
|
-
this.
|
|
537
|
-
this.
|
|
538
|
-
this.
|
|
307
|
+
class g {
|
|
308
|
+
constructor(t) {
|
|
309
|
+
this.flipMultiplier = .4 * Math.random() - .2 + 1, this.time = 0, this.stateNum = 0,
|
|
310
|
+
this.lightsFlipInterval = 20, this.states = [ [ "L", "", "L", "" ], [ "FR", "", "FR", "" ], [ "", "L", "", "L" ], [ "", "FR", "", "FR" ] ],
|
|
311
|
+
this.intersection = t;
|
|
312
|
+
}
|
|
313
|
+
get flipInterval() {
|
|
314
|
+
return this.flipMultiplier * this.lightsFlipInterval;
|
|
315
|
+
}
|
|
316
|
+
get state() {
|
|
317
|
+
let t = this.states[this.stateNum % this.states.length];
|
|
318
|
+
this.intersection.roads.length <= 2 && (t = [ "LFR", "LFR", "LFR", "LFR" ]);
|
|
319
|
+
const s = [];
|
|
320
|
+
for (let i = 0, h = t.length; i < h; i++) {
|
|
321
|
+
const h = t[i];
|
|
322
|
+
s.push(this.decode(h));
|
|
323
|
+
}
|
|
324
|
+
return s;
|
|
325
|
+
}
|
|
326
|
+
decode(t) {
|
|
327
|
+
const s = [ 0, 0, 0 ], i = [].indexOf || function(t) {
|
|
328
|
+
for (let s = 0, i = this.length; s < i; s++) if (s in this && this[s] === t) return s;
|
|
329
|
+
return -1;
|
|
330
|
+
};
|
|
331
|
+
return i.call(t, "L") >= 0 && (s[0] = 1), i.call(t, "F") >= 0 && (s[1] = 1), i.call(t, "R") >= 0 && (s[2] = 1),
|
|
332
|
+
s;
|
|
333
|
+
}
|
|
334
|
+
flip() {
|
|
335
|
+
return this.stateNum += 1;
|
|
336
|
+
}
|
|
337
|
+
onTick(t) {
|
|
338
|
+
return this.time += t, this.time > this.flipInterval ? (this.flip(), this.time -= this.flipInterval) : null;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
class w {
|
|
343
|
+
constructor(t, s) {
|
|
344
|
+
this.x = 0, this.y = 0, t && (this.x = t), s && (this.y = s);
|
|
345
|
+
}
|
|
346
|
+
get length() {
|
|
347
|
+
return Math.sqrt(this.x * this.x + this.y * this.y);
|
|
348
|
+
}
|
|
349
|
+
get direction() {
|
|
350
|
+
return Math.atan2(this.y, this.x);
|
|
351
|
+
}
|
|
352
|
+
get normalized() {
|
|
353
|
+
return new w(this.x / this.length, this.y / this.length);
|
|
354
|
+
}
|
|
355
|
+
add(t) {
|
|
356
|
+
return new w(this.x + t.x, this.y + t.y);
|
|
357
|
+
}
|
|
358
|
+
subtract(t) {
|
|
359
|
+
return new w(this.x - t.x, this.y - t.y);
|
|
360
|
+
}
|
|
361
|
+
mult(t) {
|
|
362
|
+
return new w(this.x * t, this.y * t);
|
|
363
|
+
}
|
|
364
|
+
divide(t) {
|
|
365
|
+
return new w(this.x / t, this.y / t);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
class p {
|
|
370
|
+
constructor(t, s, i, h) {
|
|
371
|
+
this.x = 0, this.y = 0, this.width = 0, this.height = 0, this.x = t || 0, this.y = s || 0,
|
|
372
|
+
this.width = i || 0, this.height = h || 0;
|
|
373
|
+
}
|
|
374
|
+
static copy(t) {
|
|
375
|
+
return new p(t.x, t.y, t.width, t.height);
|
|
376
|
+
}
|
|
377
|
+
toJSON() {
|
|
378
|
+
return Object.assign({}, this);
|
|
379
|
+
}
|
|
380
|
+
area() {
|
|
381
|
+
return this.width * this.height;
|
|
382
|
+
}
|
|
383
|
+
left(t) {
|
|
384
|
+
return void 0 !== t && (this.x = t), this.x;
|
|
385
|
+
}
|
|
386
|
+
right(t) {
|
|
387
|
+
return void 0 !== t && (this.x = t - this.width), this.x + this.width;
|
|
388
|
+
}
|
|
389
|
+
top(t) {
|
|
390
|
+
return void 0 !== t && (this.y = t), this.y;
|
|
391
|
+
}
|
|
392
|
+
bottom(t) {
|
|
393
|
+
return void 0 !== t && (this.y = t - this.height), this.y + this.height;
|
|
394
|
+
}
|
|
395
|
+
center(t) {
|
|
396
|
+
return void 0 !== t && (this.x = t.x - this.width / 2, this.y = t.y - this.height / 2),
|
|
397
|
+
new w(this.x + this.width / 2, this.y + this.height / 2);
|
|
398
|
+
}
|
|
399
|
+
containsPoint(t) {
|
|
400
|
+
let s, i;
|
|
401
|
+
return this.left() <= (s = t.x) && s <= this.right() && this.top() <= (i = t.y) && i <= this.bottom();
|
|
402
|
+
}
|
|
403
|
+
containsRect(t) {
|
|
404
|
+
return this.left() <= t.left() && t.right() <= this.right() && this.top() <= t.top() && t.bottom() <= this.bottom();
|
|
405
|
+
}
|
|
406
|
+
getVertices() {
|
|
407
|
+
return [ new w(this.left(), this.top()), new w(this.right(), this.top()), new w(this.right(), this.bottom()), new w(this.left(), this.bottom()) ];
|
|
408
|
+
}
|
|
409
|
+
getSide(t) {
|
|
410
|
+
const s = this.getVertices();
|
|
411
|
+
return new u(s[t], s[(t + 1) % 4]);
|
|
412
|
+
}
|
|
413
|
+
getSectorId(t) {
|
|
414
|
+
const s = t.subtract(this.center());
|
|
415
|
+
if (s.y <= 0 && Math.abs(s.x) <= Math.abs(s.y)) return 0;
|
|
416
|
+
if (s.x >= 0 && Math.abs(s.x) >= Math.abs(s.y)) return 1;
|
|
417
|
+
if (s.y >= 0 && Math.abs(s.x) <= Math.abs(s.y)) return 2;
|
|
418
|
+
if (s.x <= 0 && Math.abs(s.x) >= Math.abs(s.y)) return 3;
|
|
419
|
+
throw new Error("algorithm error");
|
|
420
|
+
}
|
|
421
|
+
getSector(t) {
|
|
422
|
+
return this.getSide(this.getSectorId(t));
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
class m {
|
|
427
|
+
constructor(t) {
|
|
428
|
+
this.id = r("intersection"), this.rect = t, this.roads = [], this.inRoads = [],
|
|
429
|
+
this.controlSignals = new g(this);
|
|
430
|
+
}
|
|
431
|
+
static copy(t) {
|
|
432
|
+
t.rect = p.copy(t.rect);
|
|
433
|
+
const s = Object.create(m.prototype);
|
|
434
|
+
return Object.assign(s, t), s.roads = [], s.inRoads = [], s.controlSignals = new g(s),
|
|
435
|
+
s;
|
|
436
|
+
}
|
|
437
|
+
toJSON() {
|
|
438
|
+
return {
|
|
439
|
+
id: this.id,
|
|
440
|
+
rect: this.rect
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
update() {
|
|
444
|
+
let t, s, i, h, n;
|
|
445
|
+
const e = this.roads;
|
|
446
|
+
for (s = 0, h = e.length; s < h; s++) t = e[s], t.update();
|
|
447
|
+
const r = this.inRoads, o = [];
|
|
448
|
+
for (i = 0, n = r.length; i < n; i++) t = r[i], o.push(t.update());
|
|
449
|
+
return o;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
class v {
|
|
454
|
+
constructor(t, s) {
|
|
455
|
+
let i, h, n;
|
|
456
|
+
if (this.objects = {}, this.factory = t, s && s.objects) for (i in n = s.objects,
|
|
457
|
+
n) h = n[i], this.factory instanceof d || (this.objects[i] = this.factory.copy(h));
|
|
458
|
+
}
|
|
459
|
+
get length() {
|
|
460
|
+
return Object.keys(this.objects).length;
|
|
461
|
+
}
|
|
462
|
+
toJSON() {
|
|
463
|
+
return this.objects;
|
|
464
|
+
}
|
|
465
|
+
get(t) {
|
|
466
|
+
return this.objects[t];
|
|
467
|
+
}
|
|
468
|
+
put(t) {
|
|
469
|
+
return this.objects[t.id] = t;
|
|
470
|
+
}
|
|
471
|
+
pop(t) {
|
|
472
|
+
let s;
|
|
473
|
+
const i = null !== (s = t.id) ? s : t, h = this.objects[i];
|
|
474
|
+
return h instanceof d && h.release(), delete this.objects[i], h;
|
|
475
|
+
}
|
|
476
|
+
all() {
|
|
477
|
+
return this.objects;
|
|
478
|
+
}
|
|
479
|
+
clear() {
|
|
480
|
+
return this.objects = {};
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
class M {
|
|
485
|
+
constructor(t, s, i) {
|
|
486
|
+
this.leftmostAdjacent = null, this.rightmostAdjacent = null, this.carsPositions = {},
|
|
487
|
+
this.sourceSegment = t, this.targetSegment = s, this.road = i, this.update();
|
|
539
488
|
}
|
|
540
489
|
get sourceSideId() {
|
|
541
490
|
return this.road.sourceSideId;
|
|
@@ -550,17 +499,17 @@ class E {
|
|
|
550
499
|
return this === this.leftmostAdjacent;
|
|
551
500
|
}
|
|
552
501
|
get leftBorder() {
|
|
553
|
-
return new
|
|
502
|
+
return new u(this.sourceSegment.source, this.targetSegment.target);
|
|
554
503
|
}
|
|
555
504
|
get rightBorder() {
|
|
556
|
-
return new
|
|
505
|
+
return new u(this.sourceSegment.target, this.targetSegment.source);
|
|
557
506
|
}
|
|
558
507
|
toJSON() {
|
|
559
|
-
const t =
|
|
508
|
+
const t = Object.assign({}, this);
|
|
560
509
|
return delete t.carsPositions, t;
|
|
561
510
|
}
|
|
562
511
|
update() {
|
|
563
|
-
return this.middleLine = new
|
|
512
|
+
return this.middleLine = new u(this.sourceSegment.center, this.targetSegment.center),
|
|
564
513
|
this.length = this.middleLine.length, this.direction = this.middleLine.direction;
|
|
565
514
|
}
|
|
566
515
|
getTurnDirection(t) {
|
|
@@ -582,20 +531,20 @@ class E {
|
|
|
582
531
|
}
|
|
583
532
|
getNext(t) {
|
|
584
533
|
if (t.lane !== this) throw Error("car is on other lane");
|
|
585
|
-
let
|
|
586
|
-
const
|
|
587
|
-
for (const
|
|
588
|
-
const
|
|
589
|
-
!
|
|
534
|
+
let s = null, i = 1 / 0;
|
|
535
|
+
const h = this.carsPositions;
|
|
536
|
+
for (const n in h) {
|
|
537
|
+
const e = h[n], r = e.position - t.position;
|
|
538
|
+
!e.free && 0 < r && r < i && (i = r, s = e);
|
|
590
539
|
}
|
|
591
|
-
return
|
|
540
|
+
return s;
|
|
592
541
|
}
|
|
593
542
|
}
|
|
594
543
|
|
|
595
|
-
class
|
|
596
|
-
constructor(t,
|
|
597
|
-
this.
|
|
598
|
-
this.
|
|
544
|
+
class b {
|
|
545
|
+
constructor(t, s, i) {
|
|
546
|
+
this.id = r("road"), this.lanes = [], this.lanesNumber = null, this.source = t,
|
|
547
|
+
this.target = s, this.gridSize = i || 32, this.update();
|
|
599
548
|
}
|
|
600
549
|
get length() {
|
|
601
550
|
return this.targetSide.target.subtract(this.sourceSide.source).length;
|
|
@@ -607,8 +556,8 @@ class R {
|
|
|
607
556
|
return this.lanes[0];
|
|
608
557
|
}
|
|
609
558
|
copy(t) {
|
|
610
|
-
const
|
|
611
|
-
return
|
|
559
|
+
const s = Object.create(b.prototype);
|
|
560
|
+
return Object.assign(s, t), null == s.lanes && (s.lanes = []), s;
|
|
612
561
|
}
|
|
613
562
|
toJSON() {
|
|
614
563
|
return {
|
|
@@ -619,21 +568,21 @@ class R {
|
|
|
619
568
|
}
|
|
620
569
|
getTurnDirection(t) {
|
|
621
570
|
if (this.target !== t.source) throw Error("invalid roads");
|
|
622
|
-
const
|
|
623
|
-
return (t.sourceSideId -
|
|
571
|
+
const s = this.targetSideId;
|
|
572
|
+
return (t.sourceSideId - s - 1 + 8) % 4;
|
|
624
573
|
}
|
|
625
574
|
update() {
|
|
626
|
-
let t, i,
|
|
575
|
+
let t, s, i, h, n, e;
|
|
627
576
|
if (!this.source || !this.target) throw Error("incomplete road");
|
|
628
577
|
this.sourceSideId = this.source.rect.getSectorId(this.target.rect.center()), this.sourceSide = this.source.rect.getSide(this.sourceSideId).subsegment(.5, 1),
|
|
629
578
|
this.targetSideId = this.target.rect.getSectorId(this.source.rect.center()), this.targetSide = this.target.rect.getSide(this.targetSideId).subsegment(0, .5),
|
|
630
579
|
this.lanesNumber = 0 | Math.min(this.sourceSide.length, this.targetSide.length),
|
|
631
580
|
this.lanesNumber = Math.max(2, this.lanesNumber / this.gridSize | 0);
|
|
632
|
-
const
|
|
581
|
+
const r = this.sourceSide.split(this.lanesNumber, !0), o = this.targetSide.split(this.lanesNumber);
|
|
633
582
|
if (null == this.lanes || this.lanes.length < this.lanesNumber) for (null == this.lanes && (this.lanes = []),
|
|
634
|
-
t =
|
|
583
|
+
t = i = 0, n = this.lanesNumber - 1; 0 <= n ? i <= n : i >= n; t = 0 <= n ? ++i : --i) null == (s = this.lanes)[t] && (s[t] = new M(r[t], o[t], this));
|
|
635
584
|
const u = [];
|
|
636
|
-
for (t =
|
|
585
|
+
for (t = h = 0, e = this.lanesNumber - 1; 0 <= e ? h <= e : h >= e; t = 0 <= e ? ++h : --h) this.lanes[t].sourceSegment = r[t],
|
|
637
586
|
this.lanes[t].targetSegment = o[t], this.lanes[t].leftAdjacent = this.lanes[t + 1],
|
|
638
587
|
this.lanes[t].rightAdjacent = this.lanes[t - 1], this.lanes[t].leftmostAdjacent = this.lanes[this.lanesNumber - 1],
|
|
639
588
|
this.lanes[t].rightmostAdjacent = this.lanes[0], u.push(this.lanes[t].update());
|
|
@@ -641,71 +590,70 @@ class R {
|
|
|
641
590
|
}
|
|
642
591
|
}
|
|
643
592
|
|
|
644
|
-
class
|
|
593
|
+
class L {
|
|
645
594
|
constructor(t) {
|
|
646
|
-
this.toRemove = [], this.
|
|
647
|
-
this.
|
|
648
|
-
this.
|
|
649
|
-
this.set();
|
|
595
|
+
this.toRemove = [], this.carsList = {}, this.u = 0, this.l = 0, this.p = new i("traffic"),
|
|
596
|
+
this.m = 5, this.v = "stop", this.M = [], this.L = {}, this.options = t || {}, this.carsNumber = this.options.carsNumber || 10,
|
|
597
|
+
this.gridSize = this.options.gridSize || 32, this.set();
|
|
650
598
|
}
|
|
651
599
|
run() {
|
|
652
|
-
this.
|
|
600
|
+
this.v = "running", this.C();
|
|
653
601
|
}
|
|
654
602
|
stop() {
|
|
655
|
-
this.
|
|
603
|
+
this.v = "stop";
|
|
656
604
|
}
|
|
657
605
|
remove() {
|
|
658
|
-
this.
|
|
606
|
+
this.N && cancelAnimationFrame(this.N), this.p.remove(), delete this.map;
|
|
659
607
|
}
|
|
660
608
|
setSymbols(t) {
|
|
661
|
-
this.
|
|
662
|
-
for (let t = 0; t < this.
|
|
663
|
-
const
|
|
664
|
-
this.
|
|
665
|
-
symbol:
|
|
666
|
-
}).addTo(this.
|
|
609
|
+
this.M = t;
|
|
610
|
+
for (let t = 0; t < this.M.length; t++) {
|
|
611
|
+
const s = this.M[t];
|
|
612
|
+
this.L[s.url] = new h([], {
|
|
613
|
+
symbol: s
|
|
614
|
+
}).addTo(this.p);
|
|
667
615
|
}
|
|
668
616
|
}
|
|
669
|
-
|
|
670
|
-
if ("running" !== this.
|
|
617
|
+
C() {
|
|
618
|
+
if ("running" !== this.v) return;
|
|
671
619
|
const t = Date.now();
|
|
672
620
|
this.u = t;
|
|
673
|
-
const
|
|
674
|
-
let
|
|
675
|
-
|
|
676
|
-
let
|
|
677
|
-
for (;
|
|
621
|
+
const s = Date.now();
|
|
622
|
+
let i, h = s - this.l || 0;
|
|
623
|
+
h > 100 && (h = 100), this.l = s, this.onTick(this.m * h / 1e3);
|
|
624
|
+
let n = this.toRemove.length;
|
|
625
|
+
for (;n--; ) this.I(this.toRemove[n]);
|
|
678
626
|
this.clearTmpRemove();
|
|
679
|
-
const
|
|
680
|
-
for (
|
|
681
|
-
this.
|
|
627
|
+
const e = this.cars.all();
|
|
628
|
+
for (i in e) this.R(e[i]);
|
|
629
|
+
this.N = window.requestAnimationFrame(this.C.bind(this));
|
|
682
630
|
}
|
|
683
|
-
|
|
684
|
-
for (const t in this.
|
|
631
|
+
S() {
|
|
632
|
+
for (const t in this.L) this.L[t].removeData();
|
|
685
633
|
for (const t in this.carsList) {
|
|
686
|
-
const
|
|
687
|
-
this.
|
|
634
|
+
const s = this.carsList[t], i = s.url;
|
|
635
|
+
this.L[i].addData(s);
|
|
688
636
|
}
|
|
689
637
|
}
|
|
690
|
-
R(
|
|
691
|
-
const
|
|
692
|
-
if (this.carsList[
|
|
693
|
-
if (!
|
|
694
|
-
const
|
|
695
|
-
this.carsList[
|
|
696
|
-
const u = this.
|
|
697
|
-
u > -1 ? this.
|
|
638
|
+
R(s) {
|
|
639
|
+
const i = s.id.substring(3);
|
|
640
|
+
if (this.carsList[i]) {
|
|
641
|
+
if (!s) return;
|
|
642
|
+
const h = s.coords, n = s.direction, e = this.map, r = e.pointAtResToCoordinate(new t.Point(h.x / this.gridSize, h.y / this.gridSize), e.getGLRes()), o = n / Math.PI * 180 + 90;
|
|
643
|
+
this.carsList[i].coordinates = r, this.carsList[i].rotation = [ 0, 0, o ];
|
|
644
|
+
const u = this.T(i), l = this.carsList[i].url;
|
|
645
|
+
u > -1 ? this.L[l].updateData(u, this.carsList[i]) : this.L[l].addData(this.carsList[i]);
|
|
698
646
|
} else {
|
|
699
|
-
const t = this.
|
|
700
|
-
this.carsList[
|
|
647
|
+
const t = this.M[Math.floor(Math.random() * this.M.length)];
|
|
648
|
+
this.carsList[i] = {
|
|
701
649
|
coordinates: null,
|
|
702
650
|
direction: null,
|
|
703
651
|
url: t.url
|
|
704
|
-
}, this.showHideCar(this.carsList[
|
|
652
|
+
}, this.showHideCar(this.carsList[i], "show");
|
|
705
653
|
}
|
|
706
654
|
}
|
|
707
|
-
showHideCar(
|
|
708
|
-
const
|
|
655
|
+
showHideCar(s, i, h) {
|
|
656
|
+
const n = this;
|
|
709
657
|
t.animation.Animation.animate({
|
|
710
658
|
symbol: {
|
|
711
659
|
transparent: 1
|
|
@@ -715,57 +663,46 @@ class b {
|
|
|
715
663
|
easing: "out"
|
|
716
664
|
}, (function(t) {
|
|
717
665
|
if ("running" === t.state.playState) {
|
|
718
|
-
let
|
|
719
|
-
"show" ===
|
|
720
|
-
|
|
721
|
-
const t =
|
|
722
|
-
if (!
|
|
723
|
-
const
|
|
724
|
-
t > -1 &&
|
|
666
|
+
let e = 0;
|
|
667
|
+
"show" === i ? (e = t.styles.symbol.transparent, s.color = [ 1, 1, 1, e ]) : "hide" === i && (e = 1 - t.styles.symbol.transparent,
|
|
668
|
+
s.color = [ 1, 1, 1, e ], e < .01 && setTimeout((function() {
|
|
669
|
+
const t = n.T(h);
|
|
670
|
+
if (!n.carsList[h]) return;
|
|
671
|
+
const s = n.carsList[h].url;
|
|
672
|
+
t > -1 && n.L[s].removeData(t), delete n.carsList[h];
|
|
725
673
|
}), 100));
|
|
726
674
|
}
|
|
727
675
|
})).play();
|
|
728
676
|
}
|
|
729
|
-
|
|
730
|
-
const
|
|
731
|
-
if (!
|
|
732
|
-
const
|
|
733
|
-
return this.
|
|
677
|
+
T(t) {
|
|
678
|
+
const s = this.carsList[t];
|
|
679
|
+
if (!s) return -1;
|
|
680
|
+
const i = s.url;
|
|
681
|
+
return this.L[i].getAllData().indexOf(this.carsList[t]);
|
|
734
682
|
}
|
|
735
|
-
|
|
736
|
-
const
|
|
737
|
-
null != this.carsList[
|
|
683
|
+
I(t) {
|
|
684
|
+
const s = t.substring(3);
|
|
685
|
+
null != this.carsList[s] && this.showHideCar(this.carsList[s], "hide", s);
|
|
738
686
|
}
|
|
739
687
|
get instantSpeed() {
|
|
740
|
-
const t =
|
|
741
|
-
|
|
742
|
-
return
|
|
743
|
-
n.push(i.call(s, t, e, r));
|
|
744
|
-
}), n);
|
|
745
|
-
}(this.cars.all(), t => t.speed);
|
|
746
|
-
return 0 === t.length ? 0 : function(t, i, s, n) {
|
|
747
|
-
let e = arguments.length > 2;
|
|
748
|
-
return null == t && (t = []), nativeReduce && t.reduce === nativeReduce ? (n && (i = o(i, n)),
|
|
749
|
-
e ? t.reduce(i, s) : t.reduce(i)) : (c(t, (t, r, h) => {
|
|
750
|
-
e ? s = i.call(n, s, t, r, h) : (s = t, e = !0);
|
|
751
|
-
}), s);
|
|
752
|
-
}(t, (function(t, i) {
|
|
753
|
-
return t + i;
|
|
688
|
+
const t = Object.values(this.cars.all()).map((t => t.speed));
|
|
689
|
+
return 0 === t.length ? 0 : t.reduce((function(t, s) {
|
|
690
|
+
return t + s;
|
|
754
691
|
})) / t.length;
|
|
755
692
|
}
|
|
756
693
|
get map() {
|
|
757
|
-
const t = this.
|
|
694
|
+
const t = this.j;
|
|
758
695
|
return t ? t.getMap() : null;
|
|
759
696
|
}
|
|
760
697
|
addTo(t) {
|
|
761
|
-
this.
|
|
698
|
+
this.j = t, this.p.addTo(t);
|
|
762
699
|
}
|
|
763
700
|
set(t) {
|
|
764
|
-
return null == t && (t = {}), this.intersections = new
|
|
765
|
-
this.cars = new
|
|
701
|
+
return null == t && (t = {}), this.intersections = new v(m, t.intersections), this.roads = new v(b, t.roads),
|
|
702
|
+
this.cars = new v(d, t.cars), this.carsNumber = 0;
|
|
766
703
|
}
|
|
767
704
|
save() {
|
|
768
|
-
const t =
|
|
705
|
+
const t = Object.assign({}, this);
|
|
769
706
|
return delete t.cars, window.localStorage.world = JSON.stringify(t);
|
|
770
707
|
}
|
|
771
708
|
setCarNumber(t) {
|
|
@@ -775,36 +712,36 @@ class b {
|
|
|
775
712
|
return this.carsNumber;
|
|
776
713
|
}
|
|
777
714
|
load() {
|
|
778
|
-
let t,
|
|
715
|
+
let t, s, i, h;
|
|
779
716
|
if (t = window.localStorage.world, t = t && JSON.parse(t), null == t) return null;
|
|
780
717
|
this.clear(), this.carsNumber = t.carsNumber || 0;
|
|
781
|
-
const
|
|
782
|
-
for (
|
|
783
|
-
const
|
|
784
|
-
for (
|
|
785
|
-
|
|
786
|
-
return
|
|
718
|
+
const n = t.intersections;
|
|
719
|
+
for (s in n) i = n[s], this.addIntersection(m.copy(i));
|
|
720
|
+
const e = t.roads, r = [];
|
|
721
|
+
for (s in e) h = e[s], h = (new b).copy(h), h.source = this.getIntersection(h.source),
|
|
722
|
+
h.target = this.getIntersection(h.target), r.push(this.addRoad(h));
|
|
723
|
+
return r;
|
|
787
724
|
}
|
|
788
725
|
intersectSegment(t, i) {
|
|
789
|
-
for (let
|
|
790
|
-
const
|
|
791
|
-
if (
|
|
792
|
-
intersectIndex:
|
|
793
|
-
coord:
|
|
726
|
+
for (let h = 0; h < i.length - 1; h++) {
|
|
727
|
+
const n = [ i[h], i[h + 1] ], e = s.lineString(n), r = s.lineIntersect(t, e);
|
|
728
|
+
if (r.features.length) return {
|
|
729
|
+
intersectIndex: h,
|
|
730
|
+
coord: r.features[0].geometry.coordinates
|
|
794
731
|
};
|
|
795
732
|
}
|
|
796
733
|
return null;
|
|
797
734
|
}
|
|
798
|
-
intersection(t, i,
|
|
799
|
-
const o =
|
|
800
|
-
for (let t = i + 1; t <
|
|
801
|
-
const
|
|
735
|
+
intersection(t, i, h, n, e, r) {
|
|
736
|
+
const o = s.lineString(t);
|
|
737
|
+
for (let t = i + 1; t < n.length; t++) {
|
|
738
|
+
const s = n[t], u = this.intersectSegment(o, s);
|
|
802
739
|
if (!u) continue;
|
|
803
740
|
const l = {};
|
|
804
741
|
l[i] = {
|
|
805
|
-
pre:
|
|
742
|
+
pre: h
|
|
806
743
|
}, l[t] = {
|
|
807
|
-
pre: u.intersectIndex +
|
|
744
|
+
pre: u.intersectIndex + r[t]
|
|
808
745
|
};
|
|
809
746
|
const c = {
|
|
810
747
|
inLines: l,
|
|
@@ -813,113 +750,113 @@ class b {
|
|
|
813
750
|
y: u.coord[1]
|
|
814
751
|
}, this.map.getGLRes())
|
|
815
752
|
};
|
|
816
|
-
|
|
753
|
+
e.push(c);
|
|
817
754
|
}
|
|
818
755
|
}
|
|
819
756
|
generateTraffic(t) {
|
|
820
757
|
if (!this.map) return;
|
|
821
|
-
const
|
|
822
|
-
let
|
|
823
|
-
for (let
|
|
824
|
-
const
|
|
825
|
-
let
|
|
826
|
-
for (let
|
|
827
|
-
const
|
|
828
|
-
for (let
|
|
829
|
-
const o = [ r
|
|
830
|
-
this.intersection(o,
|
|
758
|
+
const s = {};
|
|
759
|
+
let i = 0;
|
|
760
|
+
for (let h = 0; h < t.length; h++) s[h] = i, i += t[h].length;
|
|
761
|
+
const h = [];
|
|
762
|
+
let n = 0;
|
|
763
|
+
for (let i = 0; i < t.length; i++) {
|
|
764
|
+
const e = t[i];
|
|
765
|
+
for (let r = 0; r < e.length - 1; r++) {
|
|
766
|
+
const o = [ e[r], e[r + 1] ];
|
|
767
|
+
this.intersection(o, i, n + r, t, h, s);
|
|
831
768
|
}
|
|
832
|
-
|
|
769
|
+
n += e.length;
|
|
833
770
|
}
|
|
834
|
-
const
|
|
835
|
-
let
|
|
771
|
+
const e = [];
|
|
772
|
+
let r = 0;
|
|
836
773
|
const o = this.map;
|
|
837
|
-
for (let
|
|
838
|
-
const
|
|
839
|
-
for (let t = 0; t <
|
|
840
|
-
const
|
|
841
|
-
x:
|
|
842
|
-
y:
|
|
843
|
-
}, o.getGLRes()),
|
|
844
|
-
0 === t ?
|
|
774
|
+
for (let s = 0; s < t.length; s++) {
|
|
775
|
+
const i = t[s];
|
|
776
|
+
for (let t = 0; t < i.length; t++) {
|
|
777
|
+
const h = o.coordinateToPointAtRes({
|
|
778
|
+
x: i[t][0],
|
|
779
|
+
y: i[t][1]
|
|
780
|
+
}, o.getGLRes()), n = {};
|
|
781
|
+
0 === t ? n[s] = {
|
|
845
782
|
pre: null
|
|
846
|
-
} : (
|
|
847
|
-
pre: t - 1 +
|
|
783
|
+
} : (i.length, n[s] = {
|
|
784
|
+
pre: t - 1 + r
|
|
848
785
|
});
|
|
849
786
|
const u = {
|
|
850
|
-
inLines:
|
|
851
|
-
coordinate:
|
|
787
|
+
inLines: n,
|
|
788
|
+
coordinate: h
|
|
852
789
|
};
|
|
853
|
-
|
|
790
|
+
e.push(u);
|
|
854
791
|
}
|
|
855
|
-
|
|
792
|
+
r += i.length;
|
|
856
793
|
}
|
|
857
|
-
for (let t = 0; t <
|
|
858
|
-
const
|
|
859
|
-
this.comparePrePoint(
|
|
794
|
+
for (let t = 0; t < e.length; t++) {
|
|
795
|
+
const s = e[t];
|
|
796
|
+
this.comparePrePoint(s, t, h);
|
|
860
797
|
}
|
|
861
798
|
const u = this.gridSize, l = [];
|
|
862
|
-
for (let t = 0; t <
|
|
863
|
-
const
|
|
864
|
-
|
|
799
|
+
for (let t = 0; t < e.length; t++) {
|
|
800
|
+
const s = e[t], i = s.coordinate.x, h = s.coordinate.y, n = new p(i * u - .5, h * u - .5, 1, 1), r = new m(n);
|
|
801
|
+
r.connectRoads = s.roads, l.push(r), this.addIntersection(r);
|
|
865
802
|
}
|
|
866
803
|
const c = [];
|
|
867
|
-
for (let t = 0; t <
|
|
868
|
-
const
|
|
869
|
-
|
|
804
|
+
for (let t = 0; t < h.length; t++) {
|
|
805
|
+
const s = h[t], i = s.coordinate.x, n = s.coordinate.y, e = new p(i * u - .5, n * u - .5, 1, 1), r = new m(e);
|
|
806
|
+
r.connectRoads = s.roads, c.push(r), this.addIntersection(r);
|
|
870
807
|
}
|
|
871
808
|
for (let t = 0; t < l.length; t++) {
|
|
872
|
-
const
|
|
873
|
-
if (
|
|
874
|
-
const
|
|
875
|
-
if (null !=
|
|
809
|
+
const s = l[t], i = s.connectRoads;
|
|
810
|
+
if (i) for (let t = 0; t < i.length; t++) {
|
|
811
|
+
const h = i[t];
|
|
812
|
+
if (null != h.pre) {
|
|
876
813
|
let t = null;
|
|
877
|
-
const
|
|
878
|
-
"line" ===
|
|
879
|
-
this.addRoad(new
|
|
814
|
+
const i = h.type;
|
|
815
|
+
"line" === i ? t = l[h.pre] : "line-interact" === i && (t = c[h.pre]), this.addRoad(new b(s, t)),
|
|
816
|
+
this.addRoad(new b(t, s));
|
|
880
817
|
}
|
|
881
818
|
}
|
|
882
819
|
}
|
|
883
820
|
for (let t = 0; t < c.length; t++) {
|
|
884
|
-
const
|
|
885
|
-
if (
|
|
886
|
-
const
|
|
887
|
-
if (null !=
|
|
821
|
+
const s = c[t], i = s.connectRoads;
|
|
822
|
+
if (i) for (let t = 0; t < i.length; t++) {
|
|
823
|
+
const h = i[t];
|
|
824
|
+
if (null != h.pre) {
|
|
888
825
|
let t = null;
|
|
889
|
-
const
|
|
890
|
-
"line" ===
|
|
891
|
-
this.addRoad(new
|
|
826
|
+
const i = h.type;
|
|
827
|
+
"line" === i ? t = l[h.pre] : "line-interact" === i && (t = c[h.pre]), this.addRoad(new b(s, t)),
|
|
828
|
+
this.addRoad(new b(t, s));
|
|
892
829
|
}
|
|
893
830
|
}
|
|
894
831
|
}
|
|
895
832
|
}
|
|
896
|
-
comparePrePoint(t,
|
|
897
|
-
const
|
|
898
|
-
if (
|
|
899
|
-
const {pre:
|
|
900
|
-
for (let
|
|
901
|
-
const
|
|
902
|
-
|
|
903
|
-
pre:
|
|
833
|
+
comparePrePoint(t, s, i) {
|
|
834
|
+
const h = this.getPre(t);
|
|
835
|
+
if (h) {
|
|
836
|
+
const {pre: n, lineIndex: e} = h;
|
|
837
|
+
for (let h = 0; h < i.length; h++) {
|
|
838
|
+
const r = i[h];
|
|
839
|
+
r.inLines[e] && r.inLines[e].pre === n && (t.roads = [ {
|
|
840
|
+
pre: h,
|
|
904
841
|
type: "line-interact"
|
|
905
|
-
} ],
|
|
906
|
-
pre:
|
|
842
|
+
} ], r.roads ? r.roads.push({
|
|
843
|
+
pre: s - 1,
|
|
907
844
|
type: "line"
|
|
908
|
-
}) :
|
|
909
|
-
pre:
|
|
845
|
+
}) : r.roads = [ {
|
|
846
|
+
pre: s - 1,
|
|
910
847
|
type: "line"
|
|
911
848
|
} ]);
|
|
912
849
|
}
|
|
913
850
|
t.roads || (t.roads = [ {
|
|
914
|
-
pre:
|
|
851
|
+
pre: s - 1,
|
|
915
852
|
type: "line"
|
|
916
853
|
} ]);
|
|
917
854
|
}
|
|
918
855
|
}
|
|
919
856
|
getPre(t) {
|
|
920
|
-
for (const
|
|
921
|
-
pre: t.inLines[
|
|
922
|
-
lineIndex:
|
|
857
|
+
for (const s in t.inLines) if (null !== t.inLines[s].pre) return {
|
|
858
|
+
pre: t.inLines[s].pre,
|
|
859
|
+
lineIndex: s
|
|
923
860
|
};
|
|
924
861
|
return null;
|
|
925
862
|
}
|
|
@@ -927,14 +864,14 @@ class b {
|
|
|
927
864
|
return this.set({});
|
|
928
865
|
}
|
|
929
866
|
onTick(t) {
|
|
930
|
-
let
|
|
867
|
+
let s, i, h;
|
|
931
868
|
if (t > 1) throw Error("delta > 1");
|
|
932
869
|
this.refreshCars();
|
|
933
|
-
const
|
|
934
|
-
for (
|
|
935
|
-
const
|
|
936
|
-
for (
|
|
937
|
-
return
|
|
870
|
+
const n = this.intersections.all();
|
|
871
|
+
for (i in n) h = n[i], h.controlSignals.onTick(t);
|
|
872
|
+
const e = this.cars.all(), r = [];
|
|
873
|
+
for (i in e) s = e[i], s.move(t), s.alive ? r.push(void 0) : r.push(this.removeCar(s));
|
|
874
|
+
return r;
|
|
938
875
|
}
|
|
939
876
|
refreshCars() {
|
|
940
877
|
return this.cars.length < this.carsNumber && this.addRandomCar(), this.cars.length > this.carsNumber ? this.removeRandomCar() : null;
|
|
@@ -965,17 +902,18 @@ class b {
|
|
|
965
902
|
}
|
|
966
903
|
addRandomCar() {
|
|
967
904
|
let t;
|
|
968
|
-
const
|
|
969
|
-
return null !=
|
|
905
|
+
const s = e(this.roads.all());
|
|
906
|
+
return null != s && (t = e(s.lanes), null != t) ? this.addCar(new d(t)) : null;
|
|
970
907
|
}
|
|
971
908
|
removeRandomCar() {
|
|
972
|
-
const t =
|
|
909
|
+
const t = e(this.cars.all());
|
|
973
910
|
return null != t ? this.removeCar(t) : null;
|
|
974
911
|
}
|
|
975
912
|
}
|
|
976
913
|
|
|
977
|
-
"undefined" != typeof window && window.maptalks && (window.maptalks.TrafficScene =
|
|
914
|
+
"undefined" != typeof window && window.maptalks && (window.maptalks.TrafficScene = L);
|
|
978
915
|
|
|
979
|
-
export {
|
|
916
|
+
export { L as TrafficScene };
|
|
980
917
|
|
|
981
|
-
"undefined" != typeof console && console.log("@maptalks/traffic v0.
|
|
918
|
+
"undefined" != typeof console && console.log("@maptalks/traffic v0.98.0");
|
|
919
|
+
//# sourceMappingURL=maptalks.traffic.es.js.map
|