~cibersheep/unav/systemcolors

« back to all changes in this revision

Viewing changes to nav/class/Navigator.js

  • Committer: costales
  • Date: 2016-03-26 18:53:17 UTC
  • Revision ID: costales.marcos@gmail.com-20160326185317-4iau3yhe8986h5pg
Init team

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * uNav http://launchpad.net/unav
 
3
 * Copyright (C) 2015-2016 Marcos Alvarez Costales https://launchpad.net/~costales
 
4
 *
 
5
 * uNav is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License as published by
 
7
 * the Free Software Foundation; either version 2 of the License, or
 
8
 * (at your option) any later version.
 
9
 * 
 
10
 * uNav is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 */
 
15
 
 
16
function Navigator(maths, lang) {
 
17
        this.maths = maths;
 
18
        this.ui_lang = lang;
 
19
        
 
20
        this.pos_now = new Object();
 
21
                this.pos_now['lat'] = null;
 
22
                this.pos_now['lng'] = null;
 
23
        
 
24
        this.pos_start = new Object();
 
25
                this.pos_start['lat'] = null;
 
26
                this.pos_start['lng'] = null;
 
27
        
 
28
        this.pos_end = new Object();
 
29
                this.pos_end['lat'] = null;
 
30
                this.pos_end['lng'] = null;
 
31
        
 
32
        this.accu = this.ACCU4DRIVE + 1;
 
33
        this.speed = null;
 
34
 
 
35
        this.gps_device_ok = true;
 
36
        
 
37
        this.route = new Object();
 
38
                this.route['start_check_out'] = false;
 
39
                this.route['status'] = 'no'; // no | errorAPI | waiting4signal | calc | drawing | 2review | yes | out | ended
 
40
                this.route['total'] = {
 
41
                        distance: 0,
 
42
                        time: 0
 
43
                }
 
44
                this.route['track'] = {
 
45
                        ind: 0,
 
46
                        total: 0,
 
47
                        percent: 100
 
48
                };
 
49
                this.route['tracks'] = [];
 
50
                this.route['turf'] = null;
 
51
                this.route['radars'] = [];
 
52
 
 
53
        this.nearest = new Object();
 
54
                this.nearest['indication'] = '1';
 
55
                this.nearest['dist2turn'] = 0;
 
56
                this.nearest['msg'] = '';
 
57
                this.nearest['distance'] = 0;
 
58
                this.nearest['dist_track_done'] = 0;
 
59
                this.nearest['distance_total'] = 0;
 
60
                this.nearest['time'] = 0;
 
61
                this.nearest['voice'] = false;
 
62
                this.nearest['speaked'] = false;
 
63
                this.nearest['radar'] = false;
 
64
                this.nearest['radar_sound'] = false;
 
65
                this.nearest['radar_speed'] = '!';
 
66
}
 
67
 
 
68
Navigator.prototype.ACCU4DRIVE = 250;
 
69
Navigator.prototype.IS_IN_ROUTE = 95;
 
70
Navigator.prototype.MAX_START_CHECK_OUT = 250;
 
71
Navigator.prototype.DIST4INDICATION = 99; // Never > 99 for preserve voices
 
72
Navigator.prototype.SPEED_CITY = 62;
 
73
Navigator.prototype.SPEED_INTERCITY = 82;
 
74
Navigator.prototype.RADAR_IN_ROUTE = 27;
 
75
Navigator.prototype.RADARS_MAX = 60;
 
76
 
 
77
 
 
78
Navigator.prototype.set_gps_data = function(lat, lng, accu, speed) {
 
79
        // Hack: Phones are losting the signal 1/15 times #1469008
 
80
        if (this.pos_now['lat'] !== null && this.pos_now['lng'] !== null && this.gps_device_ok && accu > this.ACCU4DRIVE) {
 
81
                this.gps_device_ok = false;
 
82
                return;
 
83
        }
 
84
        else {
 
85
                this.gps_device_ok = true;
 
86
        }
 
87
        
 
88
        this.pos_now['lat'] = lat;
 
89
        this.pos_now['lng'] = lng;
 
90
        this.accuracy = parseInt(accu);
 
91
        if (speed !== null)
 
92
        this.speed = this.maths.speed2human(speed);
 
93
        else
 
94
                this.speed = 0;
 
95
}
 
96
 
 
97
Navigator.prototype.get_pos_data = function() {
 
98
        return {
 
99
                now_lat:        this.pos_now['lat'],
 
100
                now_lng:        this.pos_now['lng'],
 
101
                start_lat:      this.pos_start['lat'],
 
102
                start_lng:      this.pos_start['lng'],
 
103
                end_lat:        this.pos_end['lat'],
 
104
                end_lng:        this.pos_end['lng'],
 
105
                accu:           this.accuracy, 
 
106
                speed:          this.speed,
 
107
                gps_is_OK:      this.gps_device_ok
 
108
        };
 
109
}
 
110
 
 
111
Navigator.prototype.radars_clear = function () {
 
112
        this.route['radars'] = [];
 
113
}
 
114
 
 
115
Navigator.prototype.set_radar = function(lat, lng, speed) {
 
116
        var dist2line = 0;
 
117
        var pt_radar = turf.point([lng, lat]);
 
118
        var pt_near = turf.pointOnLine(this.route['complete_line'], pt_radar);
 
119
        
 
120
        dist2line = geolib.getDistance(
 
121
                {latitude: lat, longitude: lng},
 
122
                {latitude: pt_near.geometry.coordinates[1], longitude: pt_near.geometry.coordinates[0]}
 
123
        );
 
124
        
 
125
        if (dist2line <= this.RADAR_IN_ROUTE && this.route['radars'].length <= this.RADARS_MAX) { // Add radar
 
126
                this.route['radars'].push({
 
127
                        lat: lat,
 
128
                        lng: lng,
 
129
                        speed: speed,
 
130
                        alerted: false
 
131
                });
 
132
        }
 
133
}
 
134
 
 
135
Navigator.prototype.get_radars = function () {
 
136
        return this.route['radars'];
 
137
}
 
138
 
 
139
Navigator.prototype.set_route = function(total_m, total_s, line_encoded, tracks) {
 
140
        // Set cycle route
 
141
        this.route['status'] = 'drawing';
 
142
 
 
143
        // Total
 
144
        this.nearest['distance_total'] = total_m;
 
145
        this.nearest['time'] = total_s;
 
146
        
 
147
        // For draw line
 
148
        this.route['start_check_out'] = false;
 
149
        var coords = this.maths.decode(line_encoded, true);
 
150
        
 
151
        // Set new start/end points for markers
 
152
        this.pos_start['lat'] = coords[0][0];
 
153
        this.pos_start['lng'] = coords[0][1];
 
154
        this.pos_end['lat'] = coords[(coords.length)-1][0];
 
155
        this.pos_end['lng'] = coords[(coords.length)-1][1];
 
156
        
 
157
        // All tracks
 
158
        this.route['tracks'] = [];
 
159
        this.route['turf'] = [];
 
160
        this.route['complete_line'] = {
 
161
                "type": "Feature",
 
162
                "properties": {},
 
163
                "geometry": {
 
164
                        "type": "LineString",
 
165
                        "coordinates": this.maths.decode(line_encoded, false)
 
166
                }
 
167
        };
 
168
        
 
169
        var turf_line = [];
 
170
        var adding_coord = false;
 
171
        var instruction = '';
 
172
        
 
173
        for (i=0; i < tracks.length; i++) {
 
174
 
 
175
                // Hack roundabouts
 
176
                if (tracks[i].type == 26) {
 
177
                        switch (tracks[i].roundabout_exit_count) {
 
178
                                case 1:
 
179
                                        tracks[i].type = 261;
 
180
                                        break;
 
181
                                case 2:
 
182
                                        tracks[i].type = 262;
 
183
                                        break;
 
184
                                case 3:
 
185
                                        tracks[i].type = 263;
 
186
                                        break;
 
187
                                case 4:
 
188
                                        tracks[i].type = 264;
 
189
                                        break;
 
190
                        }
 
191
                }
 
192
                if (tracks[i].type == 27 && i > 0) {
 
193
                        switch (tracks[i-1].type) {
 
194
                                case 261:
 
195
                                        tracks[i].type = 271;
 
196
                                        break;
 
197
                                case 262:
 
198
                                        tracks[i].type = 272;
 
199
                                        break;
 
200
                                case 263:
 
201
                                        tracks[i].type = 273;
 
202
                                        break;
 
203
                                case 264:
 
204
                                        tracks[i].type = 274;
 
205
                                        break;
 
206
                                default:
 
207
                                        tracks[i].type = 27;
 
208
                        }
 
209
                }
 
210
                
 
211
                if (this.ui_lang == 'en' || this.ui_lang == 'e1' || this.ui_lang == 'e2')
 
212
                        instruction = tracks[i].instruction.slice(0, -1);
 
213
                else
 
214
                        instruction = this.compose_instruction(
 
215
                                tracks[i].type,
 
216
                                tracks[i].instruction,
 
217
                                tracks[i].street_names,
 
218
                                tracks[i].sign,
 
219
                                tracks[i].roundabout_exit_count
 
220
                        );
 
221
 
 
222
                
 
223
                // Turn indications
 
224
                if (tracks[i].type < 4 || tracks[i].type > 6)
 
225
                        this.route['tracks'].push({
 
226
                                type: tracks[i].type,
 
227
                                coordinates: [coords[tracks[i].begin_shape_index][1], coords[tracks[i].begin_shape_index][0]], // begin coord lng,lat
 
228
                                instruction: instruction,
 
229
                                distance: (tracks[i].length*1000),
 
230
                                duration: tracks[i].time,
 
231
                                way_name: tracks[i].hasOwnProperty('street_names') ? tracks[i].street_names[0] : '', // get 1st for split instruction
 
232
                                speaked: false
 
233
                        });
 
234
                else // end
 
235
                        this.route['tracks'].push({
 
236
                                type: tracks[i].type,
 
237
                                coordinates: [coords[tracks[i].begin_shape_index][1], coords[tracks[i].begin_shape_index][0]], // begin coord lng,lat
 
238
                                instruction: t("You are near to the destination"),
 
239
                                distance: 0,
 
240
                                duration: 0,
 
241
                                way_name: '',
 
242
                                speaked: false
 
243
                        });
 
244
                
 
245
                // Check Inside + near point
 
246
                if (i_coord=tracks[i].begin_shape_index != tracks[i].end_shape_index) { // Not considerate end point
 
247
                        turf_line = [];
 
248
                        for (i_coord=tracks[i].begin_shape_index; i_coord <= tracks[i].end_shape_index; i_coord++) {
 
249
                                turf_line.push([coords[i_coord][1], coords[i_coord][0]]); // lng,lat
 
250
                        }
 
251
                        this.route['turf'].push(turf.linestring(turf_line));
 
252
                }
 
253
        }
 
254
}
 
255
 
 
256
Navigator.prototype.compose_instruction = function(type, en_instruction, street_names, sign, roundabout_exit) {
 
257
        var instruction = '';
 
258
        
 
259
        switch (type) {
 
260
                case 0: // None
 
261
                        instruction = '';
 
262
                        break;
 
263
                case 1: // Start
 
264
                        instruction = t("Go");
 
265
                        break;
 
266
                case 2: // StartRight
 
267
                        instruction = t("Go to your right");
 
268
                        break;
 
269
                case 3: // StartLeft
 
270
                        instruction = t("Go to your left");
 
271
                        break;
 
272
                case 4: // Destination
 
273
                        instruction = t("You have arrived at your destination");
 
274
                        break;
 
275
                case 5: // DestinationRight
 
276
                        instruction = t("Your destination is on the right");
 
277
                        break;
 
278
                case 6: // DestinationLeft
 
279
                        instruction = t("Your destination is on the left");
 
280
                        break;
 
281
                case 7: // Becomes
 
282
                        instruction = t("Current road becomes");
 
283
                        break;
 
284
                case 8: // Continue
 
285
                        instruction = t("Continue");
 
286
                        break;
 
287
                case 9: // SlightRight
 
288
                        instruction = t("Bear right");
 
289
                        break;
 
290
                case 10: // Right
 
291
                        instruction = t("Turn right");
 
292
                        break;
 
293
                case 11: // SharpRight
 
294
                        instruction = t("Make a sharp right");
 
295
                        break;
 
296
                case 12: // UturnRight
 
297
                        instruction = t("Make a right U-turn");
 
298
                        break;
 
299
                case 13: // UturnLeft
 
300
                        instruction = t("Make a left U-turn");
 
301
                        break;
 
302
                case 14: // SharpLeft
 
303
                        instruction = t("Make a sharp left");
 
304
                        break;
 
305
                case 15: // Left
 
306
                        instruction = t("Turn left");
 
307
                        break;
 
308
                case 16: // SlightLeft
 
309
                        instruction = t("Bear left");
 
310
                        break;
 
311
                case 17: // RampStraight
 
312
                        instruction = t("Stay straight on ramp");
 
313
                        break;
 
314
                case 18: // RampRight
 
315
                        instruction = t("Turn right on ramp");
 
316
                        break;
 
317
                case 19: // RampLeft
 
318
                        instruction = t("Turn left on ramp");
 
319
                        break;
 
320
                case 20: // ExitRight
 
321
                        instruction = t("Take the exit on the right");
 
322
                        break;
 
323
                case 21: // ExitLeft
 
324
                        instruction = t("Take the exit on the left");
 
325
                        break;
 
326
                case 22: // StayStraight
 
327
                        instruction = t("Keep straight at the fork");
 
328
                        break;
 
329
                case 23: // StayRight
 
330
                        instruction = t("Keep right at the fork");
 
331
                        break;
 
332
                case 24: // StayLeft
 
333
                        instruction = t("Keep left at the fork");
 
334
                        break;
 
335
                case 25: // Merge
 
336
                        instruction = t("Merge");
 
337
                        break;
 
338
                case 26: // RoundaboutsEnter
 
339
                case 261:
 
340
                case 262:
 
341
                case 263:
 
342
                case 264:
 
343
                        instruction = t("Enter the roundabout and take the exit %1").replace('%1', roundabout_exit);
 
344
                        return instruction;
 
345
                case 27: // RoundaboutExits
 
346
                        instruction = t("Exit the roundabout");
 
347
                        return instruction;
 
348
                case 271:
 
349
                        instruction = t("Enter the roundabout and take the exit %1").replace('%1', '1');
 
350
                        return instruction;
 
351
                case 272:
 
352
                        instruction = t("Enter the roundabout and take the exit %1").replace('%1', '2');
 
353
                        return instruction;
 
354
                case 273:
 
355
                        instruction = t("Enter the roundabout and take the exit %1").replace('%1', '3');
 
356
                        return instruction;
 
357
                case 274:
 
358
                        instruction = t("Enter the roundabout and take the exit %1").replace('%1', '4');
 
359
                        return instruction;
 
360
                case 28: // FerryEnter
 
361
                        instruction = t("Take the Ferry");
 
362
                        break;
 
363
                case 29: // FerryExit
 
364
                        instruction = t("Leave the Ferry");
 
365
                        break;
 
366
        }
 
367
        
 
368
        var number = '';
 
369
        var branch = '';
 
370
        var toward = '';
 
371
        var name = '';
 
372
        var max = 0;
 
373
        if (sign) {
 
374
                if (sign.hasOwnProperty('exit_number_elements')) {
 
375
                        max = 0;
 
376
                        sign.exit_number_elements.forEach( function( item ) {
 
377
                                if (max++ < 2) {
 
378
                                        if (!number)
 
379
                                                number = item['text'];
 
380
                                        else
 
381
                                                number = number + ', ' + item['text'].trim();
 
382
                                }
 
383
                        });
 
384
                }
 
385
 
 
386
 
 
387
                if (sign.hasOwnProperty('exit_branch_elements')) {
 
388
                        max = 0;
 
389
                        sign.exit_branch_elements.forEach( function( item ) {
 
390
                                if (max++ < 2) {
 
391
                                        if (!branch)
 
392
                                                branch = item['text'];
 
393
                                        else
 
394
                                                branch = branch + ', ' + item['text'].trim();
 
395
                                }
 
396
                        });
 
397
                }
 
398
                
 
399
                if (sign.hasOwnProperty('exit_toward_elements')) {
 
400
                        max = 0;
 
401
                        sign.exit_toward_elements.forEach( function( item ) {
 
402
                                if (max++ < 2) {
 
403
                                        if (!toward)
 
404
                                                toward = item['text'];
 
405
                                        else
 
406
                                                toward = toward + ', ' + item['text'].trim();
 
407
                                }
 
408
                        });
 
409
                }
 
410
                
 
411
                if (sign.hasOwnProperty('exit_name_elements')) {
 
412
                        max = 0;
 
413
                        sign.exit_name_elements.forEach( function( item ) {
 
414
                                if (max++ < 2) {
 
415
                                        if (!name)
 
416
                                                name = item['text'];
 
417
                                        else
 
418
                                                name = name + ', ' + item['text'].trim();
 
419
                                }
 
420
                        });
 
421
                }
 
422
        }
 
423
        
 
424
        if ((type != 20 && type != 21) &&
 
425
           (street_names && !branch && !toward && !name)) {
 
426
                instruction = instruction + t(" onto %1").replace('%1', street_names);
 
427
        }
 
428
        if (number)
 
429
                instruction = instruction + t(". Exit %1").replace('%1', number);
 
430
        if (branch)
 
431
                instruction = instruction + t(" to take the %1").replace('%1', branch);
 
432
        if (toward)
 
433
                instruction = instruction + t(" toward %1").replace('%1', toward);
 
434
        if (name)
 
435
                instruction = instruction + t(", %1").replace('%1', name);
 
436
 
 
437
        return instruction;
 
438
}
 
439
 
 
440
Navigator.prototype.get_route_indication = function() {
 
441
        var voice_tmp = this.nearest['voice'];
 
442
        if (voice_tmp) // Need because ended will call here several times
 
443
                this.nearest['voice'] = false;
 
444
        
 
445
        return {
 
446
                indication:                     this.nearest['indication'],
 
447
                dist2turn:                      this.nearest['dist2turn'],
 
448
                msg:                            this.nearest['msg'],
 
449
                time:                           this.nearest['time'],
 
450
                distance:                       this.nearest['distance'],
 
451
                dist_track_done:        this.nearest['dist_track_done'],
 
452
                distance_total:         this.nearest['distance_total'],
 
453
                speed:                          this.speed,
 
454
                voice:                          voice_tmp,
 
455
                speaked:                        this.nearest['speaked'],
 
456
                radar:                          this.nearest['radar'],
 
457
                radar_sound:            this.nearest['radar_sound'],
 
458
                radar_speed:            this.nearest['radar_speed']
 
459
        };
 
460
}
 
461
 
 
462
Navigator.prototype.get_route_tracks = function() {
 
463
        return nav.route['tracks'];
 
464
}
 
465
 
 
466
Navigator.prototype.get_route_line_map = function() {
 
467
        var line_coords = [];
 
468
        var line_added = false;
 
469
        
 
470
        // For all tracks
 
471
        for (i=0; i < this.route['turf'].length; i++) {
 
472
                // For all coordenates in each track
 
473
                for (i2=0; i2 < this.route['turf'][i].geometry.coordinates.length; i2++) {
 
474
                        // Already added? Because the last of each will be the same of next start
 
475
                        line_added = false;
 
476
                        for (i3=0; i3 < line_coords.length; i3++)
 
477
                                if (this.route['turf'][i].geometry.coordinates[i2][0] == line_coords[i3][0] && this.route['turf'][i].geometry.coordinates[i2][1] == line_coords[i3][1])
 
478
                                        line_added = true;
 
479
                        // Add
 
480
                        if (!line_added)
 
481
                                line_coords.push(this.route['turf'][i].geometry.coordinates[i2]);
 
482
                }
 
483
        }
 
484
 
 
485
        return line_coords;
 
486
}
 
487
 
 
488
Navigator.prototype.update = function() {
 
489
        if (this.route['status'] != 'yes' && this.route['status'] != 'out' && this.route['status'] != 'calc_from_out')
 
490
                return
 
491
        
 
492
        var dist2line = 0;
 
493
        var pt_now = null;
 
494
        var pt_near = null;
 
495
        this.nearest['distance'] = 0;
 
496
        this.nearest['dist_track_done'] = 0;
 
497
        this.nearest['distance_total'] = 0;
 
498
        this.nearest['time'] = 0;
 
499
        this.nearest['voice'] = false;
 
500
        this.nearest['speaked'] = false;
 
501
        this.nearest['radar'] = false;
 
502
        this.nearest['radar_sound'] = false;
 
503
        
 
504
        
 
505
        // DISTANCES pos to route lines
 
506
        var all_distances = [];
 
507
        for (i=0; i < this.route['turf'].length; i++) {
 
508
                pt_now = turf.point([this.pos_now['lng'], this.pos_now['lat']]);
 
509
                pt_near = turf.pointOnLine(this.route['turf'][i], pt_now);
 
510
                dist2line = geolib.getDistance(
 
511
                        {latitude: this.pos_now['lat'], longitude: this.pos_now['lng']},
 
512
                        {latitude: pt_near.geometry.coordinates[1], longitude: pt_near.geometry.coordinates[0]}
 
513
                );
 
514
                all_distances.push(dist2line);
 
515
        }
 
516
        var ind_nearest = all_distances.indexOf(Math.min.apply(Math, all_distances));
 
517
 
 
518
 
 
519
        // STORE the nearest. There are i+1 tracks, because the turf are lines and tracks are end points of track
 
520
        this.nearest['indication'] = this.route['tracks'][ind_nearest+1]['type'];
 
521
        this.nearest['msg'] = this.route['tracks'][ind_nearest+1]['instruction'];
 
522
        this.nearest['dist2turn'] = geolib.getDistance(
 
523
                {latitude: this.pos_now['lat'], longitude: this.pos_now['lng']},
 
524
                {latitude: this.route['tracks'][ind_nearest+1]['coordinates'][1], longitude: this.route['tracks'][ind_nearest+1]['coordinates'][0]}
 
525
        );
 
526
        this.nearest['dist_track_done'] = geolib.getDistance(
 
527
                {latitude: this.pos_now['lat'], longitude: this.pos_now['lng']},
 
528
                {latitude: this.route['tracks'][ind_nearest]['coordinates'][1], longitude: this.route['tracks'][ind_nearest]['coordinates'][0]}
 
529
        );
 
530
        
 
531
        // Speak now?
 
532
        if (!this.route['tracks'][ind_nearest+1]['speaked']) {
 
533
                var dist2speed = this.DIST4INDICATION;
 
534
                if (this.speed > this.SPEED_CITY)
 
535
                        dist2speed = this.DIST4INDICATION * 3;
 
536
                if (this.speed > this.SPEED_INTERCITY)
 
537
                        dist2speed = this.DIST4INDICATION * 10;
 
538
                
 
539
                if (this.nearest['dist2turn'] < dist2speed) {
 
540
                        this.route['tracks'][ind_nearest+1]['speaked'] = true;
 
541
                        this.nearest['voice'] = true;
 
542
                        this.nearest['speaked'] = true;
 
543
                }
 
544
        }
 
545
        else {
 
546
                this.nearest['speaked'] = true;
 
547
        }
 
548
        
 
549
        // Total distance + time
 
550
        for (i=ind_nearest; i < this.route['tracks'].length; i++) {
 
551
                if (i == ind_nearest) { // Percent left
 
552
                        var percent_completed = ((this.route['tracks'][i]['distance'] - this.nearest['dist2turn']) / this.route['tracks'][i]['distance']) * 100;
 
553
                        this.nearest['time'] = this.route['tracks'][i]['duration'] - Math.abs(this.route['tracks'][i]['duration'] * percent_completed / 100);
 
554
                        this.nearest['distance'] = this.route['tracks'][i]['distance'] - Math.abs(this.route['tracks'][i]['distance'] * percent_completed / 100);
 
555
                        this.nearest['distance_total'] = this.nearest['distance'];
 
556
                }
 
557
                else {
 
558
                        this.nearest['time'] += this.route['tracks'][i]['duration'];
 
559
                        this.nearest['distance'] += this.route['tracks'][i]['distance'];
 
560
                        this.nearest['distance_total'] += this.route['tracks'][i]['distance'];
 
561
                }
 
562
        }
 
563
 
 
564
 
 
565
 
 
566
        // RADARS
 
567
        var dist_radar_nearest = 9999;
 
568
        var ind_radar_nearest = -1;
 
569
        var dist2radar = this.DIST4INDICATION;
 
570
        if (this.speed > this.SPEED_CITY)
 
571
                dist2radar = this.DIST4INDICATION * 3;
 
572
        // Get nearest
 
573
        for (i=0; i<this.route['radars'].length; i++) {
 
574
                // Is it near?
 
575
                var dist_radar = geolib.getDistance(
 
576
                        {latitude: this.pos_now['lat'], longitude: this.pos_now['lng']},
 
577
                        {latitude: this.route['radars'][i]['lat'], longitude: this.route['radars'][i]['lng']}
 
578
                );
 
579
                if (dist_radar <= dist2radar && dist_radar < dist_radar_nearest) {
 
580
                        ind_radar_nearest = i;
 
581
                        dist_radar_nearest = dist_radar;
 
582
                }
 
583
        }
 
584
        // Alert nearest?
 
585
        if (ind_radar_nearest !== -1) {
 
586
                this.nearest['radar'] = true;
 
587
                this.nearest['radar_speed'] = this.route['radars'][ind_radar_nearest]['speed'];
 
588
                if (!this.route['radars'][ind_radar_nearest]['alerted']) {
 
589
                        this.route['radars'][ind_radar_nearest]['alerted'] = true;
 
590
                        this.nearest['radar_sound'] = true;
 
591
                }
 
592
        }
 
593
 
 
594
 
 
595
 
 
596
        // UPDATE STATUS
 
597
        // On route?
 
598
        if (all_distances[ind_nearest] <= this.IS_IN_ROUTE) {
 
599
                this.route['start_check_out'] = true;
 
600
                this.set_route_status('yes');
 
601
        }
 
602
        else if ((this.route['start_check_out'] || all_distances[ind_nearest] > this.MAX_START_CHECK_OUT) && nav.get_route_status() != 'calc_from_out'){
 
603
                this.set_route_status('out');
 
604
                return;
 
605
        }
 
606
                
 
607
        // Ended?
 
608
        if (this.nearest['indication'] >= 4 && this.nearest['indication'] <= 6 && this.nearest['dist2turn'] <= (this.DIST4INDICATION/2)) {
 
609
                this.set_route_status('ended');
 
610
                return;
 
611
        }
 
612
}
 
613
 
 
614
Navigator.prototype.set_route_status = function(status) {
 
615
        this.route['status'] = status;
 
616
}
 
617
 
 
618
Navigator.prototype.get_route_status = function() {
 
619
        return this.route['status'];
 
620
}
 
621
 
 
622
Navigator.prototype.calc2coord = function(lat, lng) {
 
623
        this.set_route_status('waiting4signal');
 
624
        
 
625
        this.pos_start['lat'] = this.pos_now['lat'];
 
626
        this.pos_start['lng'] = this.pos_now['lng'];
 
627
        this.pos_end['lat'] = lat;
 
628
        this.pos_end['lng'] = lng;
 
629
 
 
630
        this.nearest['dist2turn'] = 0;
 
631
}
 
632
 
 
633
Navigator.prototype.cancel_route = function() {
 
634
        this.set_route_status('no');
 
635
        
 
636
        this.pos_start['lat'] = null;
 
637
        this.pos_start['lng'] = null;
 
638
        this.pos_end['lat'] = null;
 
639
        this.pos_end['lng'] = null;
 
640
}