FlyViewMap.qml 20.7 KB
Newer Older
1 2
/****************************************************************************
 *
Gus Grubba's avatar
Gus Grubba committed
3
 * (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
4 5 6 7 8
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/
9

10 11 12 13 14
import QtQuick                      2.11
import QtQuick.Controls             2.4
import QtLocation                   5.3
import QtPositioning                5.3
import QtQuick.Dialogs              1.2
15 16

import QGroundControl               1.0
17 18 19
import QGroundControl.Airspace      1.0
import QGroundControl.Controllers   1.0
import QGroundControl.Controls      1.0
20 21 22
import QGroundControl.FlightDisplay 1.0
import QGroundControl.FlightMap     1.0
import QGroundControl.Palette       1.0
23
import QGroundControl.ScreenTools   1.0
24 25 26
import QGroundControl.Vehicle       1.0

FlightMap {
27 28
    id:                         _root
    allowGCSLocationCenter:     true
29
    allowVehicleLocationCenter: !_keepVehicleCentered
30
    planView:                   false
31 32
    zoomLevel:                  QGroundControl.flightMapZoom
    center:                     QGroundControl.flightMapPosition
33

34 35 36 37 38 39 40
    property Item pipState: _pipState
    QGCPipState {
        id:         _pipState
        pipOverlay: _pipOverlay
        isDark:     _isFullWindowItemDark
    }

41
    property var    guidedActionsController
42
    property var    rightPanelWidth
43
    property var    planMasterController
44 45
    property bool   pipMode:                    false   // true: map is shown in a small pip mode
    property var    toolInsets                          // Insets for the center viewport area
46

47 48 49
    property var    _planMasterController:      planMasterController
    property var    _geoFenceController:        planMasterController.geoFenceController
    property var    _rallyPointController:      planMasterController.rallyPointController
Gus Grubba's avatar
Gus Grubba committed
50
    property var    _activeVehicleCoordinate:   activeVehicle ? activeVehicle.coordinate : QtPositioning.coordinate()
51
    property real   _toolButtonTopMargin:       parent.height - mainWindow.height + (ScreenTools.defaultFontPixelHeight / 2)
Gus Grubba's avatar
Gus Grubba committed
52
    property bool   _airspaceEnabled:           QGroundControl.airmapSupported ? (QGroundControl.settingsManager.airMapSettings.enableAirMap.rawValue && QGroundControl.airspaceManager.connected): false
53 54
    property var    _flyViewSettings:           QGroundControl.settingsManager.flyViewSettings
    property bool   _keepMapCenteredOnVehicle:  _flyViewSettings.keepMapCenteredOnVehicle.rawValue
55

56
    property bool   _disableVehicleTracking:    false
57 58
    property bool   _keepVehicleCentered:       pipMode ? true : false
    property bool   _saveZoomLevelSetting:      true
59

60
    function updateAirspace(reset) {
61
        if(_airspaceEnabled) {
62 63
            var coordinateNW = _root.toCoordinate(Qt.point(0,0), false /* clipToViewPort */)
            var coordinateSE = _root.toCoordinate(Qt.point(width,height), false /* clipToViewPort */)
64
            if(coordinateNW.isValid && coordinateSE.isValid) {
65
                QGroundControl.airspaceManager.setROI(coordinateNW, coordinateSE, false /*planView*/, reset)
66
            }
67
        }
68 69
    }

70 71 72 73 74 75 76 77
    function _adjustMapZoomForPipMode() {
        _saveZoomLevelSetting = false
        if (pipMode) {
            if (QGroundControl.flightMapZoom > 3) {
                zoomLevel = QGroundControl.flightMapZoom - 3
            }
        } else {
            zoomLevel = QGroundControl.flightMapZoom
78
        }
79
        _saveZoomLevelSetting = true
80 81
    }

82
    onPipModeChanged: _adjustMapZoomForPipMode()
83

84
    onVisibleChanged: {
85 86 87
        if (visible) {
            // Synchronize center position with Plan View
            center = QGroundControl.flightMapPosition
88 89 90
        }
    }

91
    onZoomLevelChanged: {
92
        if (_saveZoomLevelSetting) {
93 94 95
            QGroundControl.flightMapZoom = zoomLevel
            updateAirspace(false)
        }
96 97
    }
    onCenterChanged: {
98
        QGroundControl.flightMapPosition = center
99
        updateAirspace(false)
100
    }
101

Gus Grubba's avatar
Gus Grubba committed
102
    on_AirspaceEnabledChanged: {
103
        updateAirspace(true)
Gus Grubba's avatar
Gus Grubba committed
104 105
    }

106 107 108 109 110 111 112 113 114 115
    // We track whether the user has panned or not to correctly handle automatic map positioning
    Connections {
        target: gesture

        onPanStarted:       _disableVehicleTracking = true
        onFlickStarted:     _disableVehicleTracking = true
        onPanFinished:      panRecenterTimer.restart()
        onFlickFinished:    panRecenterTimer.restart()
    }

116 117 118 119 120 121 122 123 124 125 126 127 128 129
    function pointInRect(point, rect) {
        return point.x > rect.x &&
                point.x < rect.x + rect.width &&
                point.y > rect.y &&
                point.y < rect.y + rect.height;
    }

    property real _animatedLatitudeStart
    property real _animatedLatitudeStop
    property real _animatedLongitudeStart
    property real _animatedLongitudeStop
    property real animatedLatitude
    property real animatedLongitude

130 131
    onAnimatedLatitudeChanged: _root.center = QtPositioning.coordinate(animatedLatitude, animatedLongitude)
    onAnimatedLongitudeChanged: _root.center = QtPositioning.coordinate(animatedLatitude, animatedLongitude)
132 133 134 135 136 137 138 139 140 141 142 143 144

    NumberAnimation on animatedLatitude { id: animateLat; from: _animatedLatitudeStart; to: _animatedLatitudeStop; duration: 1000 }
    NumberAnimation on animatedLongitude { id: animateLong; from: _animatedLongitudeStart; to: _animatedLongitudeStop; duration: 1000 }

    function animatedMapRecenter(fromCoord, toCoord) {
        _animatedLatitudeStart = fromCoord.latitude
        _animatedLongitudeStart = fromCoord.longitude
        _animatedLatitudeStop = toCoord.latitude
        _animatedLongitudeStop = toCoord.longitude
        animateLat.start()
        animateLong.start()
    }

145 146 147 148 149 150 151
    function _insetRect() {
        return Qt.rect(toolInsets.leftEdgeCenterInset,
                       toolInsets.topEdgeCenterInset,
                       _root.width - toolInsets.leftEdgeCenterInset - toolInsets.rightEdgeCenterInset,
                       _root.height - toolInsets.topEdgeCenterInset - toolInsets.bottomEdgeCenterInset)
    }

152
    function recenterNeeded() {
153 154 155
        var vehiclePoint = _root.fromCoordinate(_activeVehicleCoordinate, false /* clipToViewport */)
        var insetRect = _insetRect()
        return !pointInRect(vehiclePoint, insetRect)
156 157 158
    }

    function updateMapToVehiclePosition() {
159 160 161
        if (animateLat.running || animateLong.running) {
            return
        }
162
        // We let FlightMap handle first vehicle position
163
        if (!_keepMapCenteredOnVehicle && firstVehiclePositionReceived && _activeVehicleCoordinate.isValid && !_disableVehicleTracking) {
164
            if (_keepVehicleCentered) {
165
                _root.center = _activeVehicleCoordinate
166
            } else {
DonLakeFlyer's avatar
DonLakeFlyer committed
167
                if (firstVehiclePositionReceived && recenterNeeded()) {
168 169 170 171 172 173 174 175
                    // Move the map such that the vehicle is centered within the inset area
                    var vehiclePoint = _root.fromCoordinate(_activeVehicleCoordinate, false /* clipToViewport */)
                    var insetRect = _insetRect()
                    var centerInsetPoint = Qt.point(insetRect.x + insetRect.width / 2, insetRect.y + insetRect.height / 2)
                    var centerOffset = Qt.point((_root.width / 2) - centerInsetPoint.x, (_root.height / 2) - centerInsetPoint.y)
                    var vehicleOffsetPoint = Qt.point(vehiclePoint.x + centerOffset.x, vehiclePoint.y + centerOffset.y)
                    var vehicleOffsetCoord = _root.toCoordinate(vehicleOffsetPoint, false /* clipToViewport */)
                    animatedMapRecenter(_root.center, vehicleOffsetCoord)
176 177
                }
            }
178 179 180
        }
    }

181 182
    on_ActiveVehicleCoordinateChanged: {
        if (_keepMapCenteredOnVehicle && _activeVehicleCoordinate.isValid && !_disableVehicleTracking) {
183
            _root.center = _activeVehicleCoordinate
184 185 186
        }
    }

187
    Timer {
188 189 190
        id:         panRecenterTimer
        interval:   10000
        running:    false
191
        onTriggered: {
192
            _disableVehicleTracking = false
193
            updateMapToVehiclePosition()
194 195 196
        }
    }

197 198 199 200 201 202 203
    Timer {
        interval:       500
        running:        true
        repeat:         true
        onTriggered:    updateMapToVehiclePosition()
    }

204
    QGCMapPalette { id: mapPal; lightColors: isSatelliteMap }
Don Gagne's avatar
Don Gagne committed
205

206
    Connections {
207
        target:                 _missionController
208
        ignoreUnknownSignals:   true
209
        onNewItemsFromVehicle: {
210
            var visualItems = _missionController.visualItems
211
            if (visualItems && visualItems.count !== 1) {
212
                mapFitFunctions.fitMapViewportToMissionItems()
213
                firstVehiclePositionReceived = true
214 215
            }
        }
216 217
    }

Don Gagne's avatar
Don Gagne committed
218
    MapFitFunctions {
219
        id:                         mapFitFunctions // The name for this id cannot be changed without breaking references outside of this code. Beware!
220
        map:                        _root
Don Gagne's avatar
Don Gagne committed
221
        usePlannedHomePosition:     false
222
        planMasterController:       _planMasterController
Don Gagne's avatar
Don Gagne committed
223
    }
224

225 226 227 228 229 230
    // Add trajectory lines to the map
    MapPolyline {
        id:         trajectoryPolyline
        line.width: 3
        line.color: "red"
        z:          QGroundControl.zOrderTrajectoryLines
231
        visible:    !pipMode
232 233 234 235 236 237 238 239 240 241 242

        Connections {
            target:                 QGroundControl.multiVehicleManager
            onActiveVehicleChanged: trajectoryPolyline.path = activeVehicle ? activeVehicle.trajectoryPoints.list() : []
        }

        Connections {
            target:                 activeVehicle ? activeVehicle.trajectoryPoints : null
            onPointAdded:           trajectoryPolyline.addCoordinate(coordinate)
            onUpdateLastPoint:      trajectoryPolyline.replaceCoordinate(trajectoryPolyline.pathLength() - 1, coordinate)
            onPointsCleared:        trajectoryPolyline.path = []
Don Gagne's avatar
Don Gagne committed
243
        }
244 245 246 247
    }

    // Add the vehicles to the map
    MapItemView {
248
        model: QGroundControl.multiVehicleManager.vehicles
DonLakeFlyer's avatar
DonLakeFlyer committed
249
        delegate: VehicleMapItem {
Don Gagne's avatar
Don Gagne committed
250 251
            vehicle:        object
            coordinate:     object.coordinate
252 253
            map:            _root
            size:           pipMode ? ScreenTools.defaultFontPixelHeight : ScreenTools.defaultFontPixelHeight * 3
DonLakeFlyer's avatar
DonLakeFlyer committed
254
            z:              QGroundControl.zOrderVehicles
Don Gagne's avatar
Don Gagne committed
255
        }
256 257
    }

258 259
    // Add ADSB vehicles to the map
    MapItemView {
260
        model: QGroundControl.adsbVehicleManager.adsbVehicles
261 262 263
        delegate: VehicleMapItem {
            coordinate:     object.coordinate
            altitude:       object.altitude
264
            callsign:       object.callsign
265
            heading:        object.heading
Gus Grubba's avatar
Gus Grubba committed
266
            alert:          object.alert
267
            map:            _root
268 269 270 271
            z:              QGroundControl.zOrderVehicles
        }
    }

272 273 274 275 276
    // Add the items associated with each vehicles flight plan to the map
    Repeater {
        model: QGroundControl.multiVehicleManager.vehicles

        PlanMapItems {
277 278
            map:                    _root
            largeMapView:           !pipMode
279 280
            planMasterController:   _planMasterController
            vehicle:                _vehicle
281 282 283 284 285 286 287 288

            property var _vehicle: object

            PlanMasterController {
                id: masterController
                Component.onCompleted: startStaticActiveVehicle(object)
            }
        }
289 290
    }

291
    MapItemView {
292
        model: pipMode ? undefined : _missionController.directionArrows
293 294 295 296 297 298 299 300 301

        delegate: MapLineArrow {
            fromCoord:      object ? object.coordinate1 : undefined
            toCoord:        object ? object.coordinate2 : undefined
            arrowPosition:  2
            z:              QGroundControl.zOrderWaypointLines
        }
    }

302 303
    // Allow custom builds to add map items
    CustomMapItems {
304 305
        map:            _root
        largeMapView:   !pipMode
306 307
    }

308
    GeoFenceMapVisuals {
309
        map:                    _root
310
        myGeoFenceController:   _geoFenceController
311
        interactive:            false
312
        planView:               false
Gus Grubba's avatar
Gus Grubba committed
313
        homePosition:           activeVehicle && activeVehicle.homePosition.isValid ? activeVehicle.homePosition :  QtPositioning.coordinate()
314 315
    }

316 317
    // Rally points on map
    MapItemView {
318
        model: _rallyPointController.points
319 320 321

        delegate: MapQuickItem {
            id:             itemIndicator
322 323
            anchorPoint.x:  sourceItem.anchorPointX
            anchorPoint.y:  sourceItem.anchorPointY
324 325 326 327 328 329 330 331 332 333
            coordinate:     object.coordinate
            z:              QGroundControl.zOrderMapItems

            sourceItem: MissionItemIndexLabel {
                id:         itemIndexLabel
                label:      qsTr("R", "rally point map item label")
            }
        }
    }

DonLakeFlyer's avatar
DonLakeFlyer committed
334 335
    // Camera trigger points
    MapItemView {
Gus Grubba's avatar
Gus Grubba committed
336
        model: activeVehicle ? activeVehicle.cameraTriggerPoints : 0
DonLakeFlyer's avatar
DonLakeFlyer committed
337 338 339 340 341 342 343

        delegate: CameraTriggerIndicator {
            coordinate:     object.coordinate
            z:              QGroundControl.zOrderTopMost
        }
    }

344
    // GoTo Location visuals
Don Gagne's avatar
Don Gagne committed
345
    MapQuickItem {
346 347
        id:             gotoLocationItem
        visible:        false
Don Gagne's avatar
Don Gagne committed
348
        z:              QGroundControl.zOrderMapItems
349 350
        anchorPoint.x:  sourceItem.anchorPointX
        anchorPoint.y:  sourceItem.anchorPointY
Don Gagne's avatar
Don Gagne committed
351
        sourceItem: MissionItemIndexLabel {
DonLakeFlyer's avatar
DonLakeFlyer committed
352 353
            checked:    true
            index:      -1
354
            label:      qsTr("Go here", "Go to location waypoint")
Don Gagne's avatar
Don Gagne committed
355
        }
356

Gus Grubba's avatar
Gus Grubba committed
357
        property bool inGotoFlightMode: activeVehicle ? activeVehicle.flightMode === activeVehicle.gotoFlightMode : false
358 359

        onInGotoFlightModeChanged: {
360
            if (!inGotoFlightMode && gotoLocationItem.visible) {
361
                // Hide goto indicator when vehicle falls out of guided mode
362
                gotoLocationItem.visible = false
363 364 365
            }
        }

Gus Grubba's avatar
Gus Grubba committed
366 367 368 369
        Connections {
            target: mainWindow
            onActiveVehicleChanged: {
                if (!activeVehicle) {
370
                    gotoLocationItem.visible = false
Gus Grubba's avatar
Gus Grubba committed
371
                }
372 373 374
            }
        }

375 376 377 378
        function show(coord) {
            gotoLocationItem.coordinate = coord
            gotoLocationItem.visible = true
        }
379

380 381 382 383
        function hide() {
            gotoLocationItem.visible = false
        }

384 385 386 387 388 389 390 391
        function actionConfirmed() {
            // We leave the indicator visible. The handling for onInGuidedModeChanged will hide it.
        }

        function actionCancelled() {
            hide()
        }
    }
392

393
    // Orbit editing visuals
394
    QGCMapCircleVisuals {
395 396 397 398
        id:             orbitMapCircle
        mapControl:     parent
        mapCircle:      _mapCircle
        visible:        false
399

400 401
        property alias center:              _mapCircle.center
        property alias clockwiseRotation:   _mapCircle.clockwiseRotation
402 403
        readonly property real defaultRadius: 30

Gus Grubba's avatar
Gus Grubba committed
404 405 406 407
        Connections {
            target: mainWindow
            onActiveVehicleChanged: {
                if (!activeVehicle) {
408
                    orbitMapCircle.visible = false
Gus Grubba's avatar
Gus Grubba committed
409
                }
410 411 412
            }
        }

413
        function show(coord) {
DonLakeFlyer's avatar
DonLakeFlyer committed
414
            _mapCircle.radius.rawValue = defaultRadius
415 416 417 418 419 420 421 422
            orbitMapCircle.center = coord
            orbitMapCircle.visible = true
        }

        function hide() {
            orbitMapCircle.visible = false
        }

423 424 425 426 427 428 429 430 431
        function actionConfirmed() {
            // Live orbit status is handled by telemetry so we hide here and telemetry will show again.
            hide()
        }

        function actionCancelled() {
            hide()
        }

DonLakeFlyer's avatar
DonLakeFlyer committed
432 433 434 435
        function radius() {
            return _mapCircle.radius.rawValue
        }

436 437 438 439 440
        Component.onCompleted: guidedActionsController.orbitMapCircle = orbitMapCircle

        QGCMapCircle {
            id:                 _mapCircle
            interactive:        true
DonLakeFlyer's avatar
DonLakeFlyer committed
441
            radius.rawValue:    30
442 443
            showRotation:       true
            clockwiseRotation:  true
444 445 446
        }
    }

Gus Grubba's avatar
Gus Grubba committed
447 448 449
    // ROI Location visuals
    MapQuickItem {
        id:             roiLocationItem
450
        visible:        activeVehicle && activeVehicle.isROIEnabled
Gus Grubba's avatar
Gus Grubba committed
451 452 453 454 455 456 457 458 459
        z:              QGroundControl.zOrderMapItems
        anchorPoint.x:  sourceItem.anchorPointX
        anchorPoint.y:  sourceItem.anchorPointY
        sourceItem: MissionItemIndexLabel {
            checked:    true
            index:      -1
            label:      qsTr("ROI here", "Make this a Region Of Interest")
        }

460
        //-- Visibilty controlled by actual state
Gus Grubba's avatar
Gus Grubba committed
461 462 463 464 465 466 467 468 469 470 471 472 473 474
        function show(coord) {
            roiLocationItem.coordinate = coord
        }

        function hide() {
        }

        function actionConfirmed() {
        }

        function actionCancelled() {
        }
    }

475
    // Orbit telemetry visuals
476
    QGCMapCircleVisuals {
477
        id:             orbitTelemetryCircle
478
        mapControl:     parent
Gus Grubba's avatar
Gus Grubba committed
479 480
        mapCircle:      activeVehicle ? activeVehicle.orbitMapCircle : null
        visible:        activeVehicle ? activeVehicle.orbitActive : false
481 482
    }

483 484 485 486
    MapQuickItem {
        id:             orbitCenterIndicator
        anchorPoint.x:  sourceItem.anchorPointX
        anchorPoint.y:  sourceItem.anchorPointY
Gus Grubba's avatar
Gus Grubba committed
487
        coordinate:     activeVehicle ? activeVehicle.orbitMapCircle.center : QtPositioning.coordinate()
488 489 490 491 492 493 494 495 496
        visible:        orbitTelemetryCircle.visible

        sourceItem: MissionItemIndexLabel {
            checked:    true
            index:      -1
            label:      qsTr("Orbit", "Orbit waypoint")
        }
    }

Don Gagne's avatar
Don Gagne committed
497
    // Handle guided mode clicks
498 499
    MouseArea {
        anchors.fill: parent
Don Gagne's avatar
Don Gagne committed
500

501
        QGCMenu {
DonLakeFlyer's avatar
DonLakeFlyer committed
502
            id: clickMenu
503
            property var coord
504
            QGCMenuItem {
DonLakeFlyer's avatar
DonLakeFlyer committed
505 506 507 508
                text:           qsTr("Go to location")
                visible:        guidedActionsController.showGotoLocation

                onTriggered: {
509 510
                    gotoLocationItem.show(clickMenu.coord)
                    orbitMapCircle.hide()
511
                    guidedActionsController.confirmAction(guidedActionsController.actionGoto, clickMenu.coord, gotoLocationItem)
DonLakeFlyer's avatar
DonLakeFlyer committed
512 513
                }
            }
514
            QGCMenuItem {
DonLakeFlyer's avatar
DonLakeFlyer committed
515 516
                text:           qsTr("Orbit at location")
                visible:        guidedActionsController.showOrbit
517

DonLakeFlyer's avatar
DonLakeFlyer committed
518
                onTriggered: {
519 520
                    orbitMapCircle.show(clickMenu.coord)
                    gotoLocationItem.hide()
521
                    guidedActionsController.confirmAction(guidedActionsController.actionOrbit, clickMenu.coord, orbitMapCircle)
DonLakeFlyer's avatar
DonLakeFlyer committed
522 523
                }
            }
Gus Grubba's avatar
Gus Grubba committed
524 525 526 527 528 529 530 531 532
            QGCMenuItem {
                text:           qsTr("ROI at location")
                visible:        guidedActionsController.showROI

                onTriggered: {
                    roiLocationItem.show(clickMenu.coord)
                    guidedActionsController.confirmAction(guidedActionsController.actionROI, clickMenu.coord, orbitMapCircle)
                }
            }
DonLakeFlyer's avatar
DonLakeFlyer committed
533 534
        }

Don Gagne's avatar
Don Gagne committed
535
        onClicked: {
DonLakeFlyer's avatar
DonLakeFlyer committed
536 537
            if (guidedActionsController.guidedUIVisible || (!guidedActionsController.showGotoLocation && !guidedActionsController.showOrbit)) {
                return
Gus Grubba's avatar
Gus Grubba committed
538
            }
539 540
            orbitMapCircle.hide()
            gotoLocationItem.hide()
541
            var clickCoord = _root.toCoordinate(Qt.point(mouse.x, mouse.y), false /* clipToViewPort */)
DonLakeFlyer's avatar
DonLakeFlyer committed
542
            if (guidedActionsController.showGotoLocation && guidedActionsController.showOrbit) {
543
                clickMenu.coord = clickCoord
DonLakeFlyer's avatar
DonLakeFlyer committed
544 545
                clickMenu.popup()
            } else if (guidedActionsController.showGotoLocation) {
DonLakeFlyer's avatar
DonLakeFlyer committed
546
                gotoLocationItem.show(clickCoord)
547
                guidedActionsController.confirmAction(guidedActionsController.actionGoto, clickCoord)
DonLakeFlyer's avatar
DonLakeFlyer committed
548
            } else if (guidedActionsController.showOrbit) {
549 550
                orbitMapCircle.show(clickCoord)
                guidedActionsController.confirmAction(guidedActionsController.actionOrbit, clickCoord)
Don Gagne's avatar
Don Gagne committed
551 552
            }
        }
553
    }
554

555
    // Airspace overlap support
556
    MapItemView {
557
        model:              _airspaceEnabled && QGroundControl.settingsManager.airMapSettings.enableAirspace && QGroundControl.airspaceManager.airspaceVisible ? QGroundControl.airspaceManager.airspaces.circles : []
558 559 560
        delegate: MapCircle {
            center:         object.center
            radius:         object.radius
561
            color:          object.color
Gus Grubba's avatar
Gus Grubba committed
562 563
            border.color:   object.lineColor
            border.width:   object.lineWidth
564 565 566 567
        }
    }

    MapItemView {
568
        model:              _airspaceEnabled && QGroundControl.settingsManager.airMapSettings.enableAirspace && QGroundControl.airspaceManager.airspaceVisible ? QGroundControl.airspaceManager.airspaces.polygons : []
569 570
        delegate: MapPolygon {
            path:           object.polygon
571
            color:          object.color
Gus Grubba's avatar
Gus Grubba committed
572 573
            border.color:   object.lineColor
            border.width:   object.lineWidth
574 575
        }
    }
576

577
}