merge github sandbox/zheng_wenlong/ces2019_vertical
authorzheng_wenlong <wenlong_zheng@nexty-ele.com>
Tue, 4 Dec 2018 07:27:03 +0000 (16:27 +0900)
committerzheng_wenlong <wenlong_zheng@nexty-ele.com>
Tue, 4 Dec 2018 07:27:03 +0000 (16:27 +0900)
app/BtnGuidance.qml
app/ImgDestinationDirection.qml
app/app.pro
app/file_operation.cpp [new file with mode: 0644]
app/file_operation.h
app/navigation.qml

index 18efd9f..394cb6a 100644 (file)
@@ -50,8 +50,8 @@ Item {
 \r
     Timer {\r
         id: positionTimer\r
-        interval: fileOperation.getInterval() // set millisecond\r
-        running: false\r
+        interval: fileOperation.getUpdateInterval();\r
+        running: false;\r
         repeat: true\r
         onTriggered: map.updatePositon()\r
     }\r
index b5528dd..50ae88e 100644 (file)
@@ -22,8 +22,8 @@ Item {
        states: [\r
         State {\r
             name: "0" // NoDirection\r
-            PropertyChanges { target: img_destination_direction; visible: true }\r
-            PropertyChanges { target: direction; source: "images/SW_Patern_3.bmp" }\r
+            PropertyChanges { target: img_destination_direction; visible: false }\r
+//            PropertyChanges { target: direction; source: "images/SW_Patern_3.bmp" }\r
         },\r
         State {\r
             name: "1" // DirectionForward\r
@@ -53,9 +53,9 @@ Item {
                State {\r
             name: "6" // DirectionUTurnRight\r
             PropertyChanges { target: img_destination_direction; visible: true }\r
-          //PropertyChanges { target: direction; source: "images/1_uturn.png" }\r
-            PropertyChanges { target: direction; source: "images/9_7_uturn_left.png" } // no u-turn right in CES2019\r
-               },\r
+//            PropertyChanges { target: direction; source: "images/1_uturn.png" }\r
+            PropertyChanges { target: direction; source: "images/7_left.png" } // No u-turn right in CES2019\r
+        },\r
                State {\r
             name: "7" // DirectionUTurnLeft\r
             PropertyChanges { target: img_destination_direction; visible: true }\r
index c693ee9..f058415 100644 (file)
@@ -16,7 +16,8 @@ HEADERS += \
     file_operation.h
 
 SOURCES += main.cpp \
-    dbus_server.cpp
+    dbus_server.cpp \
+    file_operation.cpp
 
 RESOURCES += \
     navigation.qrc \
diff --git a/app/file_operation.cpp b/app/file_operation.cpp
new file mode 100644 (file)
index 0000000..2be73fb
--- /dev/null
@@ -0,0 +1,83 @@
+#include "file_operation.h"
+
+File_Operation::File_Operation(){
+    initFileOperation();
+}
+
+File_Operation::~File_Operation(){
+
+}
+
+void File_Operation::initFileOperation(){
+
+    m_mapAccessToken = "";
+    m_car_speed = 60; // set default Km/h
+    m_update_interval = 100; // set default millisecond
+    m_start_latitude = 36.136261; // set default coordinate Westgate
+    m_start_longitute = -115.151254;
+
+    QFile file(MAP_ACCESS_TOKEN_FILEPATH);
+    if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){
+        fprintf(stderr,"Failed to open mapAccessToken file \"%s\": %m", qPrintable(MAP_ACCESS_TOKEN_FILEPATH));
+        return;
+    }
+
+    QByteArray data = file.readAll();
+    QJsonDocument jsonDoc(QJsonDocument::fromJson(data));
+    QJsonObject jsonObj(jsonDoc.object());
+
+    if(jsonObj.contains("mapAccessToken")){
+        m_mapAccessToken = jsonObj["mapAccessToken"].toString();
+    }else{
+        fprintf(stderr,"Failed to find mapAccessToken data \"%s\": %m", qPrintable(MAP_ACCESS_TOKEN_FILEPATH));
+        return;
+    }
+
+    if(jsonObj.contains("speed")){
+        m_car_speed = jsonObj["speed"].toDouble();
+    }else{
+        fprintf(stderr,"Failed to find speed data \"%s\": %m", qPrintable(MAP_ACCESS_TOKEN_FILEPATH));
+        return;
+    }
+
+    if(jsonObj.contains("interval")){
+        m_update_interval = jsonObj["interval"].toInt();
+    }else{
+        fprintf(stderr,"Failed to find interval data \"%s\": %m", qPrintable(MAP_ACCESS_TOKEN_FILEPATH));
+        return;
+    }
+
+    if(jsonObj.contains("latitude")){
+        m_start_latitude = jsonObj["latitude"].toDouble();
+    }else{
+        fprintf(stderr,"Failed to find latitude data \"%s\": %m", qPrintable(MAP_ACCESS_TOKEN_FILEPATH));
+        return;
+    }
+
+    if(jsonObj.contains("longitute")){
+        m_start_longitute = jsonObj["longitute"].toDouble();
+    }else{
+        fprintf(stderr,"Failed to find longitute data \"%s\": %m", qPrintable(MAP_ACCESS_TOKEN_FILEPATH));
+        return;
+    }
+
+    file.close();
+
+    return;
+}
+
+QString File_Operation::getMapAccessToken() {
+    return m_mapAccessToken;
+}
+double File_Operation::getCarSpeed(){
+    return m_car_speed;
+}
+int File_Operation::getUpdateInterval(){
+    return m_update_interval;
+}
+double File_Operation::getStartLatitude(){
+    return m_start_latitude;
+}
+double File_Operation::getStartLongitute(){
+    return m_start_longitute;
+}
index 618d26b..04b086c 100644 (file)
 #include <QObject>
 #include <QString>
 #include <QFile>
-#include <QFile>
 #include <QJsonObject>
 #include <QJsonDocument>
 
 /******************************************************
  * Write access token of mapbox in /etc/mapAccessToken
  ******************************************************/
-#define MAP_ACCESS_TOKEN_FILEPATH "/etc/mapAccessToken"
+#define MAP_ACCESS_TOKEN_FILEPATH "/etc/naviconfig.ini"
 
 class File_Operation: public QObject{
 
     Q_OBJECT
-public:
-    Q_INVOKABLE QString getMapAccessToken() {
-    #if 0
-        char buf[512];
-        QString mapAccessToken = "";
 
-        FILE* filep = fopen(qPrintable(MAP_ACCESS_TOKEN_FILEPATH), "r");
-        if (!filep) {
-            fprintf(stderr,"Failed to open mapAccessToken file \"%s\": %m", qPrintable(MAP_ACCESS_TOKEN_FILEPATH));
-            return mapAccessToken;
-        }
-        if (!fgets(buf, 512, filep)) {
-            fprintf(stderr,"Failed to read mapAccessToken from mapAccessToken file \"%s\"", qPrintable(MAP_ACCESS_TOKEN_FILEPATH));
-            fclose(filep);
-            return mapAccessToken;
-        }
-        if (strlen(buf) > 0 && buf[strlen(buf)-1] == '\n') {
-            buf[strlen(buf)-1] = '\0';
-        }
-        mapAccessToken = QString(buf);
+    QString m_mapAccessToken;
+    double m_car_speed;         // set Km/h
+    int m_update_interval;      // set millisecond
+    double m_start_latitude;
+    double m_start_longitute;
+
+public:
+    File_Operation();
+    ~File_Operation();
 
-        fclose(filep);
+    Q_INVOKABLE QString getMapAccessToken();
+    Q_INVOKABLE double getCarSpeed();
+    Q_INVOKABLE int getUpdateInterval();
+    Q_INVOKABLE double getStartLatitude();
+    Q_INVOKABLE double getStartLongitute();
 
-        return mapAccessToken;
-    #else
-       QString mapAccessToken = "";
-       QFile file(MAP_ACCESS_TOKEN_FILEPATH);
-       if (!file.open(QIODevice::ReadOnly)){
-            fprintf(stderr,"Failed to open mapAccessToken file \"%s\": %m", qPrintable(MAP_ACCESS_TOKEN_FILEPATH));
-            return mapAccessToken;
-        }
-        QByteArray data = file.readAll();
-        QJsonDocument jsonDoc(QJsonDocument::fromJson(data));
-       QJsonObject jsonObj(jsonDoc.object());
-       if(jsonObj.contains("mapAccessToken")){
-               mapAccessToken = jsonObj["mapAccessToken"].toString();
-       }else{
-               fprintf(stderr,"Failed to find mapAccessToken data \"%s\": %m", qPrintable(MAP_ACCESS_TOKEN_FILEPATH));
-       }
-       
-       file.close();
-       return mapAccessToken;
-    #endif
-    }
-    
-    Q_INVOKABLE double getSpeed() {
-       double speed = 60;      // km/h
-       QFile file(MAP_ACCESS_TOKEN_FILEPATH);
-       if (!file.open(QIODevice::ReadOnly)){
-            fprintf(stderr,"Failed to open mapAccessToken file \"%s\": %m", qPrintable(MAP_ACCESS_TOKEN_FILEPATH));
-            return speed;
-        }
-        QByteArray data = file.readAll();
-        QJsonDocument jsonDoc(QJsonDocument::fromJson(data));
-       QJsonObject jsonObj(jsonDoc.object());
-       if(jsonObj.contains("speed")){
-               speed = jsonObj["speed"].toDouble();
-       }else{
-               fprintf(stderr,"Failed to find speed data \"%s\": %m", qPrintable(MAP_ACCESS_TOKEN_FILEPATH));
-       }
-       
-       file.close();
-       return speed;
-    }
-    
-    Q_INVOKABLE int getInterval() {
-       int interval = 15;      // ms
-       QFile file(MAP_ACCESS_TOKEN_FILEPATH);
-       if (!file.open(QIODevice::ReadOnly)){
-            fprintf(stderr,"Failed to open mapAccessToken file \"%s\": %m", qPrintable(MAP_ACCESS_TOKEN_FILEPATH));
-            return interval;
-        }
-        QByteArray data = file.readAll();
-        QJsonDocument jsonDoc(QJsonDocument::fromJson(data));
-       QJsonObject jsonObj(jsonDoc.object());
-       if(jsonObj.contains("interval")){
-               interval = (int)jsonObj["interval"].toDouble();
-       }else{
-               fprintf(stderr,"Failed to find interval data \"%s\": %m", qPrintable(MAP_ACCESS_TOKEN_FILEPATH));
-       }
-       
-       file.close();
-       return interval;
-    }
-    
-    Q_INVOKABLE double getLatitude() {
-       double latitude = 36.136261;
-       QFile file(MAP_ACCESS_TOKEN_FILEPATH);
-       if (!file.open(QIODevice::ReadOnly)){
-            fprintf(stderr,"Failed to open mapAccessToken file \"%s\": %m", qPrintable(MAP_ACCESS_TOKEN_FILEPATH));
-            return latitude;
-        }
-        QByteArray data = file.readAll();
-        QJsonDocument jsonDoc(QJsonDocument::fromJson(data));
-       QJsonObject jsonObj(jsonDoc.object());
-       if(jsonObj.contains("latitude")){
-               latitude = jsonObj["latitude"].toDouble();
-       }else{
-               fprintf(stderr,"Failed to find latitude data \"%s\": %m", qPrintable(MAP_ACCESS_TOKEN_FILEPATH));
-       }
-       
-       file.close();
-       return latitude;
-    }
-    
-     Q_INVOKABLE double getLongitude() {
-       double longitute = -115.151254;
-       QFile file(MAP_ACCESS_TOKEN_FILEPATH);
-       if (!file.open(QIODevice::ReadOnly)){
-            fprintf(stderr,"Failed to open mapAccessToken file \"%s\": %m", qPrintable(MAP_ACCESS_TOKEN_FILEPATH));
-            return longitute;
-        }
-        QByteArray data = file.readAll();
-        QJsonDocument jsonDoc(QJsonDocument::fromJson(data));
-       QJsonObject jsonObj(jsonDoc.object());
-       if(jsonObj.contains("longitute")){
-               longitute = jsonObj["longitute"].toDouble();
-       }else{
-               fprintf(stderr,"Failed to find longitute data \"%s\": %m", qPrintable(MAP_ACCESS_TOKEN_FILEPATH));
-       }
-       
-       file.close();
-       return longitute;
-    }
+private:
+    void initFileOperation();
 };
 
 #endif // FILE_OPERATION_H
index ffc0ded..10e5966 100755 (executable)
@@ -29,21 +29,23 @@ ApplicationWindow {
 //    height: 680 //debug
        title: qsTr("navigation")
 
-    property real car_position_lat: fileOperation.getLatitude()     // WestGate as default
-    property real car_position_lon: fileOperation.getLongitude()
+    property real car_position_lat: fileOperation.getStartLatitude()
+    property real car_position_lon: fileOperation.getStartLongitute()
     property real car_direction: 0  //North
-    property real car_driving_speed: fileOperation.getSpeed()  // set Km/h
+    property real car_driving_speed: fileOperation.getCarSpeed()  // set Km/h
     property real prev_car_direction: 0
     property bool st_heading_up: false
     property real default_zoom_level : 18
     property real default_car_direction : 0
     property real car_accumulated_distance : 0
-    property real positionTimer_interval : fileOperation.getInterval() // set millisecond
+    property real positionTimer_interval : fileOperation.getUpdateInterval() // set millisecond
     property real car_moving_distance : (car_driving_speed / 3.6) / (1000/positionTimer_interval) // Metric unit
 
     Map{
                id: map
         property int pathcounter : 0
+        property int prevpathcounter : -1
+        property real is_rotating: 0
         property int segmentcounter : 0
         property int waypoint_count: -1
                property int lastX : -1
@@ -63,9 +65,9 @@ ApplicationWindow {
         width: parent.width
         height: parent.height
                plugin: Plugin {
-                       name: "mapboxgl"
-                       PluginParameter { name: "mapboxgl.access_token";
-                       value: fileOperation.getMapAccessToken() }
+            name: "mapboxgl"
+            PluginParameter { name: "mapboxgl.access_token";
+            value: fileOperation.getMapAccessToken() }
                }
         center: QtPositioning.coordinate(car_position_lat, car_position_lon)
         zoomLevel: default_zoom_level
@@ -138,6 +140,7 @@ ApplicationWindow {
         }
         MapQuickItem {
             id: car_position_mapitem
+            property int isRotating: 0
             sourceItem: Image {
                 id: car_position_mapitem_image
                 width: 32
@@ -166,7 +169,12 @@ ApplicationWindow {
                 }
             ]
             transitions: Transition {
-                RotationAnimation { properties: "angle"; easing.type: Easing.InOutQuad }
+                RotationAnimation {
+                    properties: "angle";
+                    easing.type: Easing.InOutQuad;
+                    direction: RotationAnimation.Shortest;
+                    duration: 200
+                }
             }
         }
 
@@ -208,11 +216,12 @@ ApplicationWindow {
 
                RouteModel {
                        id: routeModel
-                       plugin: Plugin {
-                               name: "mapbox"
-                               PluginParameter { name: "mapbox.access_token";
-                               value: fileOperation.getMapAccessToken() }
-                       }
+            plugin : Plugin {
+                name: "mapbox"
+                PluginParameter { name: "mapbox.access_token";
+                    value: fileOperation.getMapAccessToken()
+                }
+            }
                        query:  RouteQuery {
                                id: routeQuery
                        }
@@ -225,6 +234,8 @@ ApplicationWindow {
                                                break
                                        case 1:
                                                map.pathcounter = 0
+                        map.prevpathcounter = -1
+                        map.is_rotating = 0
                                                map.segmentcounter = 0
 //                                             console.log("1 route found")
 //                                             console.log("path: ", get(0).path.length, "segment: ", get(0).segments.length)
@@ -233,9 +244,9 @@ ApplicationWindow {
 //                                             }
                         console.log("1st instruction: ", get(0).segments[map.segmentcounter].maneuver.instructionText)
                         for( var i = 0; i < routeModel.get(0).segments.length; i++){
-//                            console.log("segments[",i,"].maneuver.direction:" ,routeModel.get(0).segments[i].maneuver.direction)
-//                            console.log("segments[",i,"].maneuver.instructionText:" ,routeModel.get(0).segments[i].maneuver.instructionText)
-//                            console.log("segments[",i,"].maneuver.path[0]:" ,routeModel.get(0).segments[i].path[0].latitude,",",routeModel.get(0).segments[i].path[0].longitude)
+                            console.log("segments[",i,"].maneuver.direction:" ,routeModel.get(0).segments[i].maneuver.direction)
+                            console.log("segments[",i,"].maneuver.instructionText:" ,routeModel.get(0).segments[i].maneuver.instructionText)
+                            console.log("segments[",i,"].maneuver.path[0]:" ,routeModel.get(0).segments[i].path[0].latitude,",",routeModel.get(0).segments[i].path[0].longitude)
 //                            markerModel.addMarker(routeModel.get(0).segments[i].path[0]) // for debug
                         }
                         break
@@ -255,7 +266,7 @@ ApplicationWindow {
                                line.color: "#4658da"
                                line.width: 10
                                smooth: true
-                               opacity: 0.8
+                opacity: 0.8
                        }
                }
                
@@ -338,6 +349,8 @@ ApplicationWindow {
             }
             waypoint_count = 0
             pathcounter = 0
+            prevpathcounter = -1
+            is_rotating = 0
             segmentcounter = 0
             routeModel.update();
             markerModel.removeMarker();
@@ -546,7 +559,7 @@ ApplicationWindow {
                        }
                        
                        onPressAndHold:{
-                if(btn_guidance.state !== "onGuide")
+                if((btn_guidance.state !== "onGuide") && (btn_guidance.state !== "Routing"))
                 {
                     if (Math.abs(map.pressX - mouse.x ) < map.jitterThreshold
                             && Math.abs(map.pressY - mouse.y ) < map.jitterThreshold) {
@@ -588,74 +601,93 @@ ApplicationWindow {
                                                             routeModel.get(0).segments[segmentcounter].path[0].latitude,
                                                             routeModel.get(0).segments[segmentcounter].path[0].longitude);
 //                console.log("next_cross_distance:",next_cross_distance);
-                // set next coordidnate
-                if(next_distance < (root.car_moving_distance * 1.5))
-                {
-                    map.currentpostion = routeModel.get(0).path[pathcounter]
-                    if(pathcounter != 0){
-                        car_accumulated_distance += next_distance
-                    }
-                    map.qmlSignalPosInfo(map.currentpostion.latitude, map.currentpostion.longitude,next_direction,car_accumulated_distance)
-                    if(pathcounter < routeModel.get(0).path.length - 1){
-                        pathcounter++
-                    }
-                    else
+
+                // car_position_mapitem angle
+                if(prevpathcounter !== pathcounter) {
+                    root.prev_car_direction = root.car_direction
+                    root.car_direction = next_direction
+                }
+
+                if(root.st_heading_up) {
+                    // HeadingUp
+                    is_rotating = map.bearing - root.car_direction;
+                } else {
+                    // NorthUp
+                    is_rotating = root.prev_car_direction - root.car_direction;
+                }
+
+                if(is_rotating < 0) {
+                    var val = -1;
+                    is_rotating = is_rotating * val;
+                }
+
+                if(is_rotating < 30) {
+                    // set next coordidnate
+                    if(next_distance < (root.car_moving_distance * 1.5))
                     {
-                        // Arrive at your destination
-                        btn_guidance.sts_guide = 0
-                        map.qmlSignalArrvied()
-                    }
-                }else{
-                    setNextCoordinate(map.currentpostion.latitude, map.currentpostion.longitude,next_direction,root.car_moving_distance)
-                    if(pathcounter != 0){
-                        car_accumulated_distance += root.car_moving_distance
+                        map.currentpostion = routeModel.get(0).path[pathcounter]
+                        car_accumulated_distance += next_distance
+                        map.qmlSignalPosInfo(map.currentpostion.latitude, map.currentpostion.longitude,next_direction,car_accumulated_distance)
+                        if(pathcounter < routeModel.get(0).path.length - 1){
+                            prevpathcounter = pathcounter
+                            pathcounter++
+                        }
+                        else
+                        {
+                            // Arrive at your destination
+                            btn_guidance.sts_guide = 0
+                            map.qmlSignalArrvied()
+                        }
+                    }else{
+                        setNextCoordinate(map.currentpostion.latitude, map.currentpostion.longitude,next_direction,root.car_moving_distance)
+                        if(pathcounter != 0){
+                            car_accumulated_distance += root.car_moving_distance
+                        }
+                        map.qmlSignalPosInfo(map.currentpostion.latitude, map.currentpostion.longitude,next_direction,car_accumulated_distance)
                     }
-                    map.qmlSignalPosInfo(map.currentpostion.latitude, map.currentpostion.longitude,next_direction,car_accumulated_distance)
+    //                console.log("NextCoordinate:",map.currentpostion.latitude,",",map.currentpostion.longitude)
                 }
-//                console.log("NextCoordinate:",map.currentpostion.latitude,",",map.currentpostion.longitude)
-
-                // car_position_mapitem angle
-                root.prev_car_direction = root.car_direction
-                root.car_direction = next_direction
 
                 if(btn_present_position.state === "Flowing")
                 {
                     // update map.center
                     map.center = map.currentpostion
-
-                    rotateMapSmooth()
                 }
-
-                // report a new instruction if current position matches with the head position of the segment
-                if(segmentcounter <= routeModel.get(0).segments.length - 1){
-                     if(next_cross_distance < 2){
-//                      console.log("new segment instruction: ", routeModel.get(0).segments[segmentcounter].maneuver.instructionText)
-                        progress_next_cross.setProgress(0)
-                        if(segmentcounter < routeModel.get(0).segments.length - 1){
-                            segmentcounter++
-                        }
-                        if(segmentcounter === routeModel.get(0).segments.length - 1){
-                            img_destination_direction.state = "12"
-                            map.removeMapItem(icon_segment_point)
+                rotateMapSmooth()
+
+                if(is_rotating < 30) {
+                    // report a new instruction if current position matches with the head position of the segment
+                    if(segmentcounter <= routeModel.get(0).segments.length - 1){
+                         if(next_cross_distance < 2){
+                            console.log("new segment instruction: ", routeModel.get(0).segments[segmentcounter].maneuver.instructionText) // for segment debug
+                            progress_next_cross.setProgress(0)
+                            if(segmentcounter < routeModel.get(0).segments.length - 1){
+                                segmentcounter++
+                            }
+                            if(segmentcounter === routeModel.get(0).segments.length - 1){
+                                img_destination_direction.state = "12"
+                                map.removeMapItem(icon_segment_point)
+                            }else{
+                                img_destination_direction.state = routeModel.get(0).segments[segmentcounter].maneuver.direction
+                                icon_segment_point.coordinate = routeModel.get(0).segments[segmentcounter].path[0]
+                                map.addMapItem(icon_segment_point)
+                                // console.log(routeModel.get(0).segments[segmentcounter].maneuver.instructionText) // for guidanceModule debug
+                                // guidanceModule.guidance(routeModel.get(0).segments[segmentcounter].maneuver.instructionText)
+                            }
                         }else{
-                            img_destination_direction.state = routeModel.get(0).segments[segmentcounter].maneuver.direction
-                            icon_segment_point.coordinate = routeModel.get(0).segments[segmentcounter].path[0]
-                            map.addMapItem(icon_segment_point)
-                            // console.log(routeModel.get(0).segments[segmentcounter].maneuver.instructionText)
-                            // guidanceModule.guidance(routeModel.get(0).segments[segmentcounter].maneuver.instructionText)
-                        }
-                    }else{
-                        if(next_cross_distance <= 330 && last_segmentcounter != segmentcounter) {
-                            last_segmentcounter = segmentcounter
-                            console.log(routeModel.get(0).segments[segmentcounter].maneuver.instructionText)
-                            guidanceModule.guidance(routeModel.get(0).segments[segmentcounter].maneuver.instructionText)
+                            if(next_cross_distance <= 330 && last_segmentcounter != segmentcounter) {
+                                last_segmentcounter = segmentcounter
+//                                console.log(routeModel.get(0).segments[segmentcounter].maneuver.instructionText) // for guidanceModule debug
+                                guidanceModule.guidance(routeModel.get(0).segments[segmentcounter].maneuver.instructionText)
+                            }
+                            // update progress_next_cross
+                            progress_next_cross.setProgress(next_cross_distance)
                         }
-                        // update progress_next_cross
-                        progress_next_cross.setProgress(next_cross_distance)
                     }
                 }
             }
                }
+
         function removePoiIconsSLOT(category_id){
             console.log("called removePoiIcons")
             while(poiArray.length>0)
@@ -677,50 +709,19 @@ ApplicationWindow {
         }
 
         function rotateMapSmooth(){
-            var prev = root.prev_car_direction
-            var now = root.car_direction
-            var diff
-
             if(root.st_heading_up){
-
-                diff = now - prev
-
-                if ( 180 < diff ){
-                    diff = diff - 360.0
-                } else if ( diff < -180 ){
-                    diff = diff + 360.0
-                }
-
-                //console.log("prev:", prev, ", now:", now, ", diff:", diff)
-
-                if( 0 < diff ){
-                    rot_anim.direction = RotationAnimation.Clockwise
-                } else {
-                    rot_anim.direction = RotationAnimation.Counterclockwise
-                }
-
                 map.state = "none"
                 map.state = "smooth_rotate"
             }else{
-                diff = 0 - prev
-
-                if ( 180 < diff ){
-                    diff = diff - 360.0
-                } else if ( diff < -180 ){
-                    diff = diff + 360.0
-                }
-
-                //console.log("prev:", prev, ", now:", now, ", diff:", diff)
-                if( 0 < diff ){
-                    rot_anim.direction = RotationAnimation.Clockwise
-                } else {
-                    rot_anim.direction = RotationAnimation.Counterclockwise
-                }
-
                 map.state = "smooth_rotate_north"
             }
         }
 
+        function stopMapRotation(){
+            map.state = "none"
+            rot_anim.stop()
+        }
+
         states: [
             State {
                 name: "none"
@@ -740,6 +741,7 @@ ApplicationWindow {
             RotationAnimation {
                 id: rot_anim
                 property: "bearing"
+                direction: RotationAnimation.Shortest
                 easing.type: Easing.InOutQuad
                 duration: 200
             }