MapScale.qml 7.68 KB
Newer Older
1 2 3 4 5 6 7 8 9
/****************************************************************************
 *
 *   (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

10 11
import QtQuick          2.3
import QtQuick.Controls 1.2
12

13 14 15 16
import QGroundControl                   1.0
import QGroundControl.Controls          1.0
import QGroundControl.ScreenTools       1.0
import QGroundControl.SettingsManager   1.0
17 18 19 20

/// Map scale control
Item {
    id:     scale
21
    width:  zoomButtonsOnLeft || !_zoomButtonsVisible ? rightEnd.x + rightEnd.width : zoomDownButton.x + zoomDownButton.width
22 23
    height: rightEnd.y + rightEnd.height

24 25 26
    property var    mapControl                  ///< Map control for which this scale control is being used
    property bool   zoomButtonsVisible: true
    property bool   zoomButtonsOnLeft:  true    ///< Zoom buttons to left/right of scale bar
27

Don Gagne's avatar
Don Gagne committed
28 29
    property variant _scaleLengthsMeters: [5, 10, 25, 50, 100, 150, 250, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 2000000]
    property variant _scaleLengthsFeet: [10, 25, 50, 100, 250, 500, 1000, 2000, 3000, 4000, 5280, 5280*2, 5280*5, 5280*10, 5280*25, 5280*50, 5280*100, 5280*250, 5280*500, 5280*1000]
30

31 32
    property bool _zoomButtonsVisible:  zoomButtonsVisible && !ScreenTools.isMobile // Zoom buttons don't show on mobile since finger pinch works fine

33
    property var _color: mapControl.isSatelliteMap ? "white" : "black"
34

Don Gagne's avatar
Don Gagne committed
35
    function formatDistanceMeters(meters) {
36 37 38 39
        var dist = Math.round(meters)
        if (dist > 1000 ){
            if (dist > 100000){
                dist = Math.round(dist / 1000)
Don Gagne's avatar
Don Gagne committed
40
            } else {
41 42 43
                dist = Math.round(dist / 100)
                dist = dist / 10
            }
Don Gagne's avatar
Don Gagne committed
44 45 46
            dist = dist + qsTr(" km")
        } else {
            dist = dist + qsTr(" m")
47
        }
Don Gagne's avatar
Don Gagne committed
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
        return dist
    }

    function formatDistanceFeet(feet) {
        var dist = Math.round(feet)
        if (dist >= 5280) {
            dist = Math.round(dist / 5280)
            dist = dist
            if (dist == 1) {
                dist += qsTr(" mile")
            } else {
                dist += qsTr(" miles")
            }
        } else {
            dist = dist + qsTr(" ft")
63 64 65 66
        }
        return dist
    }

Don Gagne's avatar
Don Gagne committed
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
    function calculateMetersRatio(scaleLineMeters, scaleLinePixelLength) {
        var scaleLineRatio = 0

        if (scaleLineMeters === 0) {
            // not visible
        } else {
            for (var i = 0; i < _scaleLengthsMeters.length - 1; i++) {
                if (scaleLineMeters < (_scaleLengthsMeters[i] + _scaleLengthsMeters[i+1]) / 2 ) {
                    scaleLineRatio = _scaleLengthsMeters[i] / scaleLineMeters
                    scaleLineMeters = _scaleLengthsMeters[i]
                    break;
                }
            }
            if (scaleLineRatio === 0) {
                scaleLineRatio = scaleLineMeters / _scaleLengthsMeters[i]
                scaleLineMeters = _scaleLengthsMeters[i]
            }
        }

        var text = formatDistanceMeters(scaleLineMeters)
        centerLine.width = (scaleLinePixelLength * scaleLineRatio) - (2 * leftEnd.width)
        scaleText.text = text
    }

    function calculateFeetRatio(scaleLineMeters, scaleLinePixelLength) {
        var scaleLineRatio = 0
        var scaleLineFeet = scaleLineMeters * 3.2808399

        if (scaleLineFeet === 0) {
96 97
            // not visible
        } else {
Don Gagne's avatar
Don Gagne committed
98 99 100 101
            for (var i = 0; i < _scaleLengthsFeet.length - 1; i++) {
                if (scaleLineFeet < (_scaleLengthsFeet[i] + _scaleLengthsFeet[i+1]) / 2 ) {
                    scaleLineRatio = _scaleLengthsFeet[i] / scaleLineFeet
                    scaleLineFeet = _scaleLengthsFeet[i]
102 103 104
                    break;
                }
            }
Don Gagne's avatar
Don Gagne committed
105 106 107
            if (scaleLineRatio === 0) {
                scaleLineRatio = scaleLineFeet / _scaleLengthsFeet[i]
                scaleLineFeet = _scaleLengthsFeet[i]
108 109
            }
        }
Don Gagne's avatar
Don Gagne committed
110 111 112

        var text = formatDistanceFeet(scaleLineFeet)
        centerLine.width = (scaleLinePixelLength * scaleLineRatio) - (2 * leftEnd.width)
113 114 115
        scaleText.text = text
    }

Don Gagne's avatar
Don Gagne committed
116
    function calculateScale() {
117 118 119 120 121 122 123 124 125 126
        if(mapControl) {
            var scaleLinePixelLength = 100
            var leftCoord  = mapControl.toCoordinate(Qt.point(0, scale.y), false /* clipToViewPort */)
            var rightCoord = mapControl.toCoordinate(Qt.point(scaleLinePixelLength, scale.y), false /* clipToViewPort */)
            var scaleLineMeters = Math.round(leftCoord.distanceTo(rightCoord))
            if (QGroundControl.settingsManager.unitsSettings.distanceUnits.value === UnitsSettings.DistanceUnitsFeet) {
                calculateFeetRatio(scaleLineMeters, scaleLinePixelLength)
            } else {
                calculateMetersRatio(scaleLineMeters, scaleLinePixelLength)
            }
Don Gagne's avatar
Don Gagne committed
127 128 129
        }
    }

130
    Connections {
131 132 133
        target:             mapControl
        onWidthChanged:     scaleTimer.restart()
        onHeightChanged:    scaleTimer.restart()
134 135 136 137
        onZoomLevelChanged: scaleTimer.restart()
    }

    Timer {
138 139 140 141 142
        id:                 scaleTimer
        interval:           100
        running:            false
        repeat:             false
        onTriggered:        calculateScale()
143 144
    }

145
    QGCMapLabel {
146 147 148 149
        id:                 scaleText
        map:                mapControl
        font.family:        ScreenTools.demiboldFontFamily
        anchors.left:       parent.left
150
        anchors.right:      rightEnd.right
151 152
        horizontalAlignment:Text.AlignRight
        text:               "0 m"
153 154 155
    }

    Rectangle {
156 157
        id:                 leftEnd
        anchors.top:        scaleText.bottom
158 159
        anchors.leftMargin: zoomButtonsOnLeft && _zoomButtonsVisible ? ScreenTools.defaultFontPixelWidth / 2 : 0
        anchors.left:       zoomButtonsOnLeft && _zoomButtonsVisible ? zoomDownButton.right : parent.left
160 161 162
        width:              2
        height:             ScreenTools.defaultFontPixelHeight
        color:              _color
163 164 165
    }

    Rectangle {
166
        id:                 centerLine
167
        anchors.bottomMargin:   2
168 169 170 171
        anchors.bottom:     leftEnd.bottom
        anchors.left:       leftEnd.right
        height:             2
        color:              _color
172 173 174
    }

    Rectangle {
175 176 177 178 179 180
        id:                 rightEnd
        anchors.top:        leftEnd.top
        anchors.left:       centerLine.right
        width:              2
        height:             ScreenTools.defaultFontPixelHeight
        color:              _color
181 182
    }

183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
    QGCButton {
        id:                 zoomUpButton
        anchors.top:        scaleText.top
        anchors.bottom:     rightEnd.bottom
        anchors.leftMargin: zoomButtonsOnLeft ? 0 : ScreenTools.defaultFontPixelWidth / 2
        anchors.left:       zoomButtonsOnLeft ? parent.left : rightEnd.right
        text:               qsTr("+")
        width:              height
        opacity:            0.75
        visible:            _zoomButtonsVisible
        onClicked:          mapControl.zoomLevel += 0.5
    }

    QGCButton {
        id:                 zoomDownButton
        anchors.leftMargin: ScreenTools.defaultFontPixelWidth / 2
        anchors.left:       zoomUpButton.right
        text:               qsTr("-")
        height:             zoomUpButton.height
        width:              zoomUpButton.width
        opacity:            0.75
        visible:            _zoomButtonsVisible
        onClicked:          mapControl.zoomLevel -= 0.5
    }

208 209 210 211 212 213
    Component.onCompleted: {
        if (scale.visible) {
            calculateScale();
        }
    }
}