merge github
[apps/navigation.git] / app / navigation.qml
1 /*
2  * Copyright (C) 2016 The Qt Company Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 import QtQuick 2.6
18 import QtQuick.Layouts 1.1
19 import QtQuick.Controls 2.0
20 import QtWebSockets 1.0
21 import QtLocation 5.9
22 import QtPositioning 5.6
23
24 ApplicationWindow {
25         id: root
26         visible: true
27         width: 1080
28     height: 1488
29 //    height: 680 //debug
30         title: qsTr("navigation")
31
32     property real car_position_lat: fileOperation.getStartLatitude()
33     property real car_position_lon: fileOperation.getStartLongitute()
34     property real car_direction: 0  //North
35     property real car_driving_speed: fileOperation.getCarSpeed()  // set Km/h
36     property real prev_car_direction: 0
37     property bool st_heading_up: false
38     property real default_zoom_level : 18
39     property real default_car_direction : 0
40     property real car_accumulated_distance : 0
41     property real positionTimer_interval : fileOperation.getUpdateInterval() // set millisecond
42     property real car_moving_distance : (car_driving_speed / 3.6) / (1000/positionTimer_interval) // Metric unit
43
44     Map{
45                 id: map
46         property int pathcounter : 0
47         property int prevpathcounter : -1
48         property real is_rotating: 0
49         property int segmentcounter : 0
50         property int waypoint_count: -1
51                 property int lastX : -1
52                 property int lastY : -1
53                 property int pressX : -1
54                 property int pressY : -1
55                 property int jitterThreshold : 30
56         property variant currentpostion : QtPositioning.coordinate(car_position_lat, car_position_lon)
57         property var poiArray: new Array
58         property int last_segmentcounter : -1
59
60         signal qmlSignalRouteInfo(double srt_lat,double srt_lon,double end_lat,double end_lon);
61         signal qmlSignalPosInfo(double lat,double lon,double drc,double dst);
62         signal qmlSignalStopDemo();
63         signal qmlSignalArrvied();
64
65         width: parent.width
66         height: parent.height
67                 plugin: Plugin {
68             name: "mapboxgl"
69             PluginParameter { name: "mapboxgl.access_token";
70             value: fileOperation.getMapAccessToken() }
71                 }
72         center: QtPositioning.coordinate(car_position_lat, car_position_lon)
73         zoomLevel: default_zoom_level
74         bearing: 0
75         objectName: "map"
76
77                 GeocodeModel {
78                         id: geocodeModel
79                         plugin: map.plugin
80                         onStatusChanged: {
81                                 if ((status == GeocodeModel.Ready) || (status == GeocodeModel.Error))
82                                         map.geocodeFinished()
83                         }
84                         onLocationsChanged:
85                         {
86                                 if (count == 1) {
87                                         map.center.latitude = get(0).coordinate.latitude
88                                         map.center.longitude = get(0).coordinate.longitude
89                                 }
90                         }
91             //coordinate: poiTheQtComapny.coordinate
92             //anchorPoint: Qt.point(-poiTheQtComapny.sourceItem.width * 0.5,poiTheQtComapny.sourceItem.height * 1.5)
93         }
94                 MapItemView {
95                         model: geocodeModel
96                         delegate: pointDelegate
97                 }
98                 Component {
99                         id: pointDelegate
100
101                         MapCircle {
102                                 id: point
103                                 radius: 1000
104                                 color: "#46a2da"
105                                 border.color: "#190a33"
106                                 border.width: 2
107                                 smooth: true
108                                 opacity: 0.25
109                                 center: locationData.coordinate
110                         }
111                 }
112
113                 function geocode(fromAddress)
114                 {
115                         // send the geocode request
116                         geocodeModel.query = fromAddress
117                         geocodeModel.update()
118                 }
119                 
120         MapQuickItem {
121             id: poi
122             sourceItem: Rectangle { width: 14; height: 14; color: "#e41e25"; border.width: 2; border.color: "white"; smooth: true; radius: 7 }
123             coordinate {
124                 latitude: 36.136261
125                 longitude: -115.151254
126             }
127             opacity: 1.0
128             anchorPoint: Qt.point(sourceItem.width/2, sourceItem.height/2)
129         }
130         MapQuickItem {
131             sourceItem: Text{
132                 text: "Westgate"
133                 color:"#242424"
134                 font.bold: true
135                 styleColor: "#ECECEC"
136                 style: Text.Outline
137             }
138             coordinate: poi.coordinate
139             anchorPoint: Qt.point(-poi.sourceItem.width * 0.5, poi.sourceItem.height * 1.5)
140         }
141         MapQuickItem {
142             id: car_position_mapitem
143             property int isRotating: 0
144             sourceItem: Image {
145                 id: car_position_mapitem_image
146                 width: 32
147                 height: 32
148                 source: "images/240px-Red_Arrow_Up.svg.png"
149
150                 transform: Rotation {
151                     id: car_position_mapitem_image_rotate
152                     origin.x: car_position_mapitem_image.width/2
153                     origin.y: car_position_mapitem_image.height/2
154                     angle: car_direction
155                 }
156             }
157             anchorPoint: Qt.point(car_position_mapitem_image.width/2, car_position_mapitem_image.height/2)
158             coordinate: map.currentpostion
159
160
161             states: [
162                 State {
163                     name: "HeadingUp"
164                     PropertyChanges { target: car_position_mapitem_image_rotate; angle: 0 }
165                 },
166                 State {
167                     name: "NorthUp"
168                     PropertyChanges { target: car_position_mapitem_image_rotate; angle: root.car_direction }
169                 }
170             ]
171             transitions: Transition {
172                 RotationAnimation {
173                     properties: "angle";
174                     easing.type: Easing.InOutQuad;
175                     direction: RotationAnimation.Shortest;
176                     duration: 200
177                 }
178             }
179         }
180
181         MapQuickItem {
182             id: icon_start_point
183             anchorPoint.x: icon_start_point_image.width/2
184             anchorPoint.y: icon_start_point_image.height
185             sourceItem: Image {
186                 id: icon_start_point_image
187                 width: 32
188                 height: 32
189                 source: "images/240px-HEB_project_flow_icon_04_checkered_flag.svg.png"
190             }
191         }
192
193         MapQuickItem {
194             id: icon_end_point
195             anchorPoint.x: icon_end_point_image.width/2
196             anchorPoint.y: icon_end_point_image.height
197             sourceItem: Image {
198                 id: icon_end_point_image
199                 width: 32
200                 height: 32
201                 source: "images/Map_marker_icon_–_Nicolas_Mollet_–_Flag_–_Tourism_–_Classic.png"
202             }
203         }
204
205         MapQuickItem {
206             id: icon_segment_point
207             anchorPoint.x: icon_segment_point_image.width/2 - 5
208             anchorPoint.y: icon_segment_point_image.height/2 + 25
209             sourceItem: Image {
210                 id: icon_segment_point_image
211                 width: 64
212                 height: 64
213                 source: "images/Map_symbol_location_02.png"
214             }
215         }
216
217                 RouteModel {
218                         id: routeModel
219             plugin : Plugin {
220                 name: "mapbox"
221                 PluginParameter { name: "mapbox.access_token";
222                     value: fileOperation.getMapAccessToken()
223                 }
224             }
225                         query:  RouteQuery {
226                                 id: routeQuery
227                         }
228                         onStatusChanged: {
229                                 if (status == RouteModel.Ready) {
230                                         switch (count) {
231                                         case 0:
232                                                 // technically not an error
233                                         //      map.routeError()
234                                                 break
235                                         case 1:
236                                                 map.pathcounter = 0
237                         map.prevpathcounter = -1
238                         map.is_rotating = 0
239                                                 map.segmentcounter = 0
240 //                                              console.log("1 route found")
241 //                                              console.log("path: ", get(0).path.length, "segment: ", get(0).segments.length)
242 //                                              for(var i = 0; i < get(0).path.length; i++){
243 //                                                      console.log("", get(0).path[i])
244 //                                              }
245                         console.log("1st instruction: ", get(0).segments[map.segmentcounter].maneuver.instructionText)
246                         for( var i = 0; i < routeModel.get(0).segments.length; i++){
247                             console.log("segments[",i,"].maneuver.direction:" ,routeModel.get(0).segments[i].maneuver.direction)
248                             console.log("segments[",i,"].maneuver.instructionText:" ,routeModel.get(0).segments[i].maneuver.instructionText)
249                             console.log("segments[",i,"].maneuver.path[0]:" ,routeModel.get(0).segments[i].path[0].latitude,",",routeModel.get(0).segments[i].path[0].longitude)
250 //                            markerModel.addMarker(routeModel.get(0).segments[i].path[0]) // for debug
251                         }
252                         break
253                                         }
254                                 } else if (status == RouteModel.Error) {
255                                 //      map.routeError()
256                                 }
257                         }
258                 }
259                 
260                 Component {
261                         id: routeDelegate
262
263                         MapRoute {
264                                 id: route
265                                 route: routeData
266                                 line.color: "#4658da"
267                                 line.width: 10
268                                 smooth: true
269                 opacity: 0.8
270                         }
271                 }
272                 
273                 MapItemView {
274                         model: routeModel
275                         delegate: routeDelegate
276                 }
277
278         MapItemView{
279             model: markerModel
280             delegate: mapcomponent
281         }
282
283         Component {
284             id: mapcomponent
285             MapQuickItem {
286                 id: icon_destination_point
287                 anchorPoint.x: icon_destination_point_image.width/4
288                 anchorPoint.y: icon_destination_point_image.height
289                 coordinate: position
290
291                 sourceItem: Image {
292                     id: icon_destination_point_image
293                     width: 32
294                     height: 32
295                     source: "images/200px-Black_close_x.svg.png"
296                 }
297             }
298         }
299
300         function addDestination(coord){
301             if( waypoint_count < 0 ){
302                 initDestination()
303             }
304
305             if(waypoint_count == 0)  {
306                 // set icon_start_point
307                 icon_start_point.coordinate = currentpostion
308                 map.addMapItem(icon_start_point)
309             }
310
311             if(waypoint_count < 9){
312                 routeQuery.addWaypoint(coord)
313                 waypoint_count += 1
314
315                 btn_guidance.sts_guide = 1
316                 btn_guidance.state = "Routing"
317
318                 var waypointlist = routeQuery.waypoints
319                 for(var i=1; i<waypoint_count; i++) {
320                     markerModel.addMarker(waypointlist[i])
321
322 //                    map.addPoiIconSLOT(waypointlist[i].latitude,waypointlist[i].longitude,i % 5) // for Debug
323                 }
324
325                 routeModel.update()
326                 map.qmlSignalRouteInfo(car_position_lat, car_position_lon,coord.latitude,coord.longitude)
327
328                 // update icon_end_point
329                 icon_end_point.coordinate = coord
330                 map.addMapItem(icon_end_point)
331             }
332         }
333
334         function initDestination(){
335             routeModel.reset();
336             console.log("initWaypoint")
337
338             // reset currentpostion
339             map.currentpostion = QtPositioning.coordinate(car_position_lat, car_position_lon)
340             car_accumulated_distance = 0
341             map.qmlSignalPosInfo(car_position_lat, car_position_lon,car_direction,car_accumulated_distance)
342
343             routeQuery.clearWaypoints();
344             routeQuery.addWaypoint(map.currentpostion)
345             routeQuery.travelModes = RouteQuery.CarTravel
346             routeQuery.routeOptimizations = RouteQuery.FastestRoute
347             for (var i=0; i<9; i++) {
348                 routeQuery.setFeatureWeight(i, 0)
349             }
350             waypoint_count = 0
351             pathcounter = 0
352             prevpathcounter = -1
353             is_rotating = 0
354             segmentcounter = 0
355             routeModel.update();
356             markerModel.removeMarker();
357             map.removeMapItem(markerModel);
358
359             // remove MapItem
360             map.removeMapItem(icon_start_point)
361             map.removeMapItem(icon_end_point)
362             map.removeMapItem(icon_segment_point)
363
364             // for Debug
365 //            while(poiArray.length>0)
366 //                map.removeMapItem(poiArray.pop())
367
368             // update car_position_mapitem angle
369             root.car_direction = root.default_car_direction
370
371         }
372
373                 function calculateMarkerRoute()
374                 {
375             var startCoordinate = QtPositioning.coordinate(car_position_lat, car_position_lon)
376
377                         console.log("calculateMarkerRoute")
378                         routeQuery.clearWaypoints();
379             routeQuery.addWaypoint(startCoordinate)
380             routeQuery.addWaypoint(mouseArea.lastCoordinate)
381                         routeQuery.travelModes = RouteQuery.CarTravel
382                         routeQuery.routeOptimizations = RouteQuery.FastestRoute
383                         for (var i=0; i<9; i++) {
384                                 routeQuery.setFeatureWeight(i, 0)
385                         }
386                         routeModel.update();
387                 }
388
389         // Calculate direction from latitude and longitude between two points
390         function calculateDirection(lat1, lon1, lat2, lon2) {
391             var curlat = lat1 * Math.PI / 180;
392             var curlon = lon1 * Math.PI / 180;
393             var taglat = lat2 * Math.PI / 180;
394             var taglon = lon2 * Math.PI / 180;
395
396             var Y  = Math.sin(taglon - curlon);
397             var X  = Math.cos(curlat) * Math.tan(taglat) - Math.sin(curlat) * Math.cos(Y);
398             var direction = 180 * Math.atan2(Y,X) / Math.PI;
399             if (direction < 0) {
400               direction = direction + 360;
401             }
402             return direction;
403         }
404
405         // Calculate distance from latitude and longitude between two points
406         function calculateDistance(lat1, lon1, lat2, lon2)
407         {
408             var radLat1 = lat1 * Math.PI / 180;
409             var radLon1 = lon1 * Math.PI / 180;
410             var radLat2 = lat2 * Math.PI / 180;
411             var radLon2 = lon2 * Math.PI / 180;
412
413             var r = 6378137.0;
414
415             var averageLat = (radLat1 - radLat2) / 2;
416             var averageLon = (radLon1 - radLon2) / 2;
417             var result = r * 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(averageLat), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(averageLon), 2)));
418             return Math.round(result);
419         }
420
421         // Setting the next car position from the direction and demonstration mileage
422         function setNextCoordinate(curlat,curlon,direction,distance)
423         {
424             var radian = direction * Math.PI / 180
425             var lat_per_meter = 111319.49079327358;
426             var lat_distance = distance * Math.cos(radian);
427             var addlat = lat_distance / lat_per_meter
428             var lon_distance = distance * Math.sin(radian)
429             var lon_per_meter = (Math.cos( (curlat+addlat) / 180 * Math.PI) * 2 * Math.PI * 6378137) / 360;
430             var addlon = lon_distance / lon_per_meter
431             map.currentpostion = QtPositioning.coordinate(curlat+addlat, curlon+addlon);
432         }
433
434         function addPoiIconSLOT(lat,lon,type) {
435             console.log("called addPoiIcon")
436             var poiItem;
437             switch(type){
438                 case 0:
439                     poiItem = Qt.createQmlObject("
440                             import QtQuick 2.0;
441                             import QtLocation 5.9;
442                             MapQuickItem {
443                                 id: poi_icon;
444                                 anchorPoint.x: icon_flag_liteblue_image.width/2;
445                                 anchorPoint.y: icon_flag_liteblue_image.height;
446                                 sourceItem: Image {
447                                     id: icon_flag_liteblue_image;
448                                     width: 32;
449                                     height: 37;
450                                     source: \"images/Flag-export_lightblue.png\";
451                                 }
452                             }
453                         ",map,"dynamic");
454                     break;
455                 case 1:
456                     poiItem = Qt.createQmlObject("
457                             import QtQuick 2.0;
458                             import QtLocation 5.9;
459                             MapQuickItem {
460                                 id: poi_icon;
461                                 anchorPoint.x: icon_building_image.width/2;
462                                 anchorPoint.y: icon_building_image.height;
463                                 sourceItem: Image {
464                                     id: icon_building_image;
465                                     width: 32;
466                                     height: 37;
467                                     source: \"images/BuildingIcon.png\";
468                                 }
469                             }
470                         ",map,"dynamic");
471                     break;
472                 case 2:
473                     poiItem = Qt.createQmlObject("
474                             import QtQuick 2.0;
475                             import QtLocation 5.9;
476                             MapQuickItem {
477                                 id: poi_icon;
478                                 anchorPoint.x: icon_church_image.width/2;
479                                 anchorPoint.y: icon_church_image.height;
480                                 sourceItem: Image {
481                                     id: icon_church_image;
482                                     width: 32;
483                                     height: 37;
484                                     source: \"images/ChurchIcon.png\";
485                                 }
486                             }
487                         ",map,"dynamic");
488                     break;
489                 case 3:
490                     poiItem = Qt.createQmlObject("
491                             import QtQuick 2.0;
492                             import QtLocation 5.9;
493                             MapQuickItem {
494                                 id: poi_icon;
495                                 anchorPoint.x: icon_restaurant_image.width/2;
496                                 anchorPoint.y: icon_restaurant_image.height;
497                                 sourceItem: Image {
498                                     id: icon_restaurant_image;
499                                     width: 32;
500                                     height: 37;
501                                     source: \"images/RestaurantMapIcon.png\";
502                                 }
503                             }
504                         ",map,"dynamic");
505                     break;
506                 case 4:
507                     poiItem = Qt.createQmlObject("
508                             import QtQuick 2.0;
509                             import QtLocation 5.9;
510                             MapQuickItem {
511                                 id: poi_icon;
512                                 anchorPoint.x: icon_supermarket_image.width/2;
513                                 anchorPoint.y: icon_supermarket_image.height;
514                                 sourceItem: Image {
515                                     id: icon_supermarket_image;
516                                     width: 32;
517                                     height: 37;
518                                     source: \"images/SupermarketMapIcon.png\";
519                                 }
520                             }
521                         ",map,"dynamic");
522                     break;
523                 default:
524                     poiItem = null;
525                     break;
526             }
527
528             if(poiItem === null) {
529                console.log("error creating object" +  poiItem.errorString());
530                return false;
531             }
532
533             poiItem.coordinate = QtPositioning.coordinate(lat, lon);
534             map.addMapItem(poiItem);
535             poiArray.push(poiItem);
536 //            console.log("success creating object");
537             return true;
538         }
539
540                 MouseArea {
541                         id: mouseArea
542                         property variant lastCoordinate
543                         anchors.fill: parent
544                         acceptedButtons: Qt.LeftButton | Qt.RightButton
545                         
546                         onPressed : {
547                                 map.lastX = mouse.x
548                                 map.lastY = mouse.y
549                                 map.pressX = mouse.x
550                                 map.pressY = mouse.y
551                                 lastCoordinate = map.toCoordinate(Qt.point(mouse.x, mouse.y))
552                         }
553                         
554                         onPositionChanged: {
555                 if (mouse.button === Qt.LeftButton) {
556                                         map.lastX = mouse.x
557                                         map.lastY = mouse.y
558                                 }
559                         }
560                         
561                         onPressAndHold:{
562                 if((btn_guidance.state !== "onGuide") && (btn_guidance.state !== "Routing"))
563                 {
564                     if (Math.abs(map.pressX - mouse.x ) < map.jitterThreshold
565                             && Math.abs(map.pressY - mouse.y ) < map.jitterThreshold) {
566                         map.addDestination(lastCoordinate)
567                     }
568                 }
569
570                         }
571                 }
572         gesture.onFlickStarted: {
573             btn_present_position.state = "Optional"
574         }
575         gesture.onPanStarted: {
576             btn_present_position.state = "Optional"
577         }
578                 function updatePositon()
579                 {
580 //                      console.log("updatePositon")
581             if(pathcounter <= routeModel.get(0).path.length - 1){
582 //                console.log("path: ", pathcounter, "/", routeModel.get(0).path.length - 1, " segment: ", segmentcounter, "/", routeModel.get(0).segments.length - 1)
583 //                console.log("from_to:",map.currentpostion.latitude,",",map.currentpostion.longitude,",",routeModel.get(0).path[pathcounter].latitude,",",routeModel.get(0).path[pathcounter].longitude)
584                 // calculate distance
585                 var next_distance = calculateDistance(map.currentpostion.latitude,
586                                                       map.currentpostion.longitude,
587                                                       routeModel.get(0).path[pathcounter].latitude,
588                                                       routeModel.get(0).path[pathcounter].longitude);
589 //                console.log("next_distance:",next_distance);
590
591                 // calculate direction
592                 var next_direction = calculateDirection(map.currentpostion.latitude,
593                                                         map.currentpostion.longitude,
594                                                         routeModel.get(0).path[pathcounter].latitude,
595                                                         routeModel.get(0).path[pathcounter].longitude);
596 //                console.log("next_direction:",next_direction);
597
598                 // calculate next cross distance
599                 var next_cross_distance = calculateDistance(map.currentpostion.latitude,
600                                                             map.currentpostion.longitude,
601                                                             routeModel.get(0).segments[segmentcounter].path[0].latitude,
602                                                             routeModel.get(0).segments[segmentcounter].path[0].longitude);
603 //                console.log("next_cross_distance:",next_cross_distance);
604
605                 // car_position_mapitem angle
606                 if(prevpathcounter !== pathcounter) {
607                     root.prev_car_direction = root.car_direction
608                     root.car_direction = next_direction
609                 }
610
611                 if(root.st_heading_up) {
612                     // HeadingUp
613                     is_rotating = map.bearing - root.car_direction;
614                 } else {
615                     // NorthUp
616                     is_rotating = root.prev_car_direction - root.car_direction;
617                 }
618
619                 if(is_rotating < 0) {
620                     var val = -1;
621                     is_rotating = is_rotating * val;
622                 }
623
624                 if(is_rotating < 30) {
625                     // set next coordidnate
626                     if(next_distance < (root.car_moving_distance * 1.5))
627                     {
628                         map.currentpostion = routeModel.get(0).path[pathcounter]
629                         car_accumulated_distance += next_distance
630                         map.qmlSignalPosInfo(map.currentpostion.latitude, map.currentpostion.longitude,next_direction,car_accumulated_distance)
631                         if(pathcounter < routeModel.get(0).path.length - 1){
632                             prevpathcounter = pathcounter
633                             pathcounter++
634                         }
635                         else
636                         {
637                             // Arrive at your destination
638                             btn_guidance.sts_guide = 0
639                             map.qmlSignalArrvied()
640                         }
641                     }else{
642                         setNextCoordinate(map.currentpostion.latitude, map.currentpostion.longitude,next_direction,root.car_moving_distance)
643                         if(pathcounter != 0){
644                             car_accumulated_distance += root.car_moving_distance
645                         }
646                         map.qmlSignalPosInfo(map.currentpostion.latitude, map.currentpostion.longitude,next_direction,car_accumulated_distance)
647                     }
648     //                console.log("NextCoordinate:",map.currentpostion.latitude,",",map.currentpostion.longitude)
649                 }
650
651                 if(btn_present_position.state === "Flowing")
652                 {
653                     // update map.center
654                     map.center = map.currentpostion
655                 }
656                 rotateMapSmooth()
657
658                 if(is_rotating < 30) {
659                     // report a new instruction if current position matches with the head position of the segment
660                     if(segmentcounter <= routeModel.get(0).segments.length - 1){
661                          if(next_cross_distance < 2){
662                             console.log("new segment instruction: ", routeModel.get(0).segments[segmentcounter].maneuver.instructionText) // for segment debug
663                             progress_next_cross.setProgress(0)
664                             if(segmentcounter < routeModel.get(0).segments.length - 1){
665                                 segmentcounter++
666                             }
667                             if(segmentcounter === routeModel.get(0).segments.length - 1){
668                                 img_destination_direction.state = "12"
669                                 map.removeMapItem(icon_segment_point)
670                             }else{
671                                 img_destination_direction.state = routeModel.get(0).segments[segmentcounter].maneuver.direction
672                                 icon_segment_point.coordinate = routeModel.get(0).segments[segmentcounter].path[0]
673                                 map.addMapItem(icon_segment_point)
674                                 // console.log(routeModel.get(0).segments[segmentcounter].maneuver.instructionText) // for guidanceModule debug
675                                 // guidanceModule.guidance(routeModel.get(0).segments[segmentcounter].maneuver.instructionText)
676                             }
677                         }else{
678                             if(next_cross_distance <= 330 && last_segmentcounter != segmentcounter) {
679                                 last_segmentcounter = segmentcounter
680 //                                console.log(routeModel.get(0).segments[segmentcounter].maneuver.instructionText) // for guidanceModule debug
681                                 guidanceModule.guidance(routeModel.get(0).segments[segmentcounter].maneuver.instructionText)
682                             }
683                             // update progress_next_cross
684                             progress_next_cross.setProgress(next_cross_distance)
685                         }
686                     }
687                 }
688             }
689                 }
690
691         function removePoiIconsSLOT(category_id){
692             console.log("called removePoiIcons")
693             while(poiArray.length>0)
694                 map.removeMapItem(poiArray.pop())
695         }
696
697         function doGetRouteInfoSlot(){
698             if(btn_guidance.sts_guide == 0){ // idle
699                 console.log("called doGetRouteInfoSlot sts_guide == idle")
700                 map.qmlSignalPosInfo(car_position_lat, car_position_lon,car_direction,car_accumulated_distance);
701             }else if(btn_guidance.sts_guide == 1){ // Routing
702                 console.log("called doGetRouteInfoSlot sts_guide == Routing")
703                 map.qmlSignalPosInfo(car_position_lat, car_position_lon,car_direction,car_accumulated_distance);
704                 map.qmlSignalRouteInfo(car_position_lat, car_position_lon,routeQuery.waypoints[1].latitude,routeQuery.waypoints[1].longitude);
705             }else if(btn_guidance.sts_guide == 2){ // onGuide
706                 console.log("called doGetRouteInfoSlot sts_guide == onGuide")
707                 map.qmlSignalRouteInfo(car_position_lat, car_position_lon,routeQuery.waypoints[1].latitude,routeQuery.waypoints[1].longitude);
708             }
709         }
710
711         function rotateMapSmooth(){
712             if(root.st_heading_up){
713                 map.state = "none"
714                 map.state = "smooth_rotate"
715             }else{
716                 map.state = "smooth_rotate_north"
717             }
718         }
719
720         function stopMapRotation(){
721             map.state = "none"
722             rot_anim.stop()
723         }
724
725         states: [
726             State {
727                 name: "none"
728             },
729             State {
730                 name: "smooth_rotate"
731                 PropertyChanges { target: map; bearing: root.car_direction }
732             },
733             State {
734                 name: "smooth_rotate_north"
735                 PropertyChanges { target: map; bearing: 0 }
736             }
737         ]
738
739         transitions: Transition {
740             NumberAnimation { properties: "center"; easing.type: Easing.InOutQuad }
741             RotationAnimation {
742                 id: rot_anim
743                 property: "bearing"
744                 direction: RotationAnimation.Shortest
745                 easing.type: Easing.InOutQuad
746                 duration: 200
747             }
748         }
749     }
750                 
751     BtnPresentPosition {
752         id: btn_present_position
753         anchors.right: parent.right
754         anchors.rightMargin: 125
755         anchors.bottom: parent.bottom
756         anchors.bottomMargin: 125
757     }
758
759         BtnMapDirection {
760         id: btn_map_direction
761         anchors.top: parent.top
762         anchors.topMargin: 25
763         anchors.left: parent.left
764         anchors.leftMargin: 25
765         }
766
767     BtnGuidance {
768         id: btn_guidance
769         anchors.top: parent.top
770         anchors.topMargin: 25
771         anchors.right: parent.right
772         anchors.rightMargin: 125
773         }
774
775         BtnShrink {
776         id: btn_shrink
777         anchors.left: parent.left
778         anchors.leftMargin: 25
779         anchors.bottom: parent.bottom
780         anchors.bottomMargin: 250
781         }
782
783         BtnEnlarge {
784         id: btn_enlarge
785         anchors.left: parent.left
786         anchors.leftMargin: 25
787         anchors.bottom: parent.bottom
788         anchors.bottomMargin: 125
789         }
790
791         ImgDestinationDirection {
792         id: img_destination_direction
793         anchors.top: parent.top
794         anchors.topMargin: 25
795         anchors.left: parent.left
796         anchors.leftMargin: 150
797         }
798
799     ProgressNextCross {
800         id: progress_next_cross
801         anchors.top: parent.top
802         anchors.topMargin: 25
803         anchors.left: img_destination_direction.right
804         anchors.leftMargin: 20
805         }
806 }