Newer
Older
import QtQuick 2.3
import QtQuick.Controls 1.2
import QGroundControl.ScreenTools 1.0
import QGroundControl.Vehicle 1.0
import QGroundControl.Controls 1.0
import QGroundControl.FactControls 1.0
import QGroundControl.Palette 1.0
import QGroundControl.FlightMap 1.0
// Editor for Survery mission items
Rectangle {
id: _root
height: visible ? (editorColumn.height + (_margin * 2)) : 0
width: availableWidth
color: qgcPal.windowShadeDark
radius: _radius
// The following properties must be available up the hierarchy chain
//property real availableWidth ///< Width for control
//property var missionItem ///< Mission Item for editor
property real _margin: ScreenTools.defaultFontPixelWidth / 2
property int _cameraIndex: 1
property real _fieldWidth: ScreenTools.defaultFontPixelWidth * 10.5
property var _cameraList: [ qsTr("Manual Grid (no camera specs)"), qsTr("Custom Camera Grid") ]
property var _vehicle: QGroundControl.multiVehicleManager.activeVehicle ? QGroundControl.multiVehicleManager.activeVehicle : QGroundControl.multiVehicleManager.offlineEditingVehicle
property var _vehicleCameraList: _vehicle.cameraList
readonly property int _gridTypeManual: 0
readonly property int _gridTypeCustomCamera: 1
readonly property int _gridTypeCamera: 2
Component.onCompleted: {
for (var i=0; i<_vehicle.cameraList.length; i++) {
_cameraList.push(_vehicle.cameraList[i].name)
gridTypeCombo.model = _cameraList
gridTypeCombo.currentIndex = _gridTypeManual
} else {
var index = -1
for (index=0; index<_cameraList.length; index++) {
if (_cameraList[index] == missionItem.camera.value) {
break;
}
}
missionItem.cameraOrientationFixed = false
if (index == -1) {
gridTypeCombo.currentIndex = _gridTypeManual
} else {
gridTypeCombo.currentIndex = index
if (index != 1) {
// Specific camera is selected
missionItem.cameraOrientationFixed = _vehicleCameraList[index - _gridTypeCamera].fixedOrientation
}
var focalLength = missionItem.cameraFocalLength.rawValue
var sensorWidth = missionItem.cameraSensorWidth.rawValue
var sensorHeight = missionItem.cameraSensorHeight.rawValue
var imageWidth = missionItem.cameraResolutionWidth.rawValue
var imageHeight = missionItem.cameraResolutionHeight.rawValue
var altitude = missionItem.gridAltitude.rawValue
var groundResolution= missionItem.groundResolution.rawValue
var frontalOverlap = missionItem.frontalOverlap.rawValue
var sideOverlap = missionItem.sideOverlap.rawValue
if (focalLength <= 0 || sensorWidth <= 0 || sensorHeight <= 0 || imageWidth <= 0 || imageHeight <= 0 || groundResolution <= 0) {
var imageSizeSideGround //size in side (non flying) direction of the image on the ground
var imageSizeFrontGround //size in front (flying) direction of the image on the ground
if (missionItem.fixedValueIsAltitude.value) {
groundResolution = (altitude * sensorWidth * 100) / (imageWidth * focalLength)
} else {
altitude = (imageWidth * groundResolution * focalLength) / (sensorWidth * 100)
}
if (missionItem.cameraOrientationLandscape.value) {
imageSizeSideGround = (imageWidth * groundResolution) / 100
imageSizeFrontGround = (imageHeight * groundResolution) / 100
imageSizeSideGround = (imageHeight * groundResolution) / 100
imageSizeFrontGround = (imageWidth * groundResolution) / 100
gridSpacing = imageSizeSideGround * ( (100-sideOverlap) / 100 )
cameraTriggerDistance = imageSizeFrontGround * ( (100-frontalOverlap) / 100 )
if (missionItem.fixedValueIsAltitude.value) {
missionItem.groundResolution.rawValue = groundResolution
} else {
missionItem.gridAltitude.rawValue = altitude
}
missionItem.gridSpacing.rawValue = gridSpacing
missionItem.cameraTriggerDistance.rawValue = cameraTriggerDistance
}
function polygonCaptureFinished(coordinates) {
for (var i=0; i<coordinates.length; i++) {
missionItem.addPolygonCoordinate(coordinates[i])
function polygonAdjustVertex(vertexIndex, vertexCoordinate) {
missionItem.adjustPolygonCoordinate(vertexIndex, vertexCoordinate)
function polygonAdjustStarted() { }
function polygonAdjustFinished() { }
property bool _noCameraValueRecalc: false ///< Prevents uneeded recalcs
Connections {
target: missionItem.camera
onValueChanged: {
if (gridTypeCombo.currentIndex >= _gridTypeCustomCamera && !_noCameraValueRecalc) {
recalcFromCameraValues()
}
}
}
Connections {
target: missionItem.gridAltitude
onValueChanged: {
if (gridTypeCombo.currentIndex >= _gridTypeCustomCamera && missionItem.fixedValueIsAltitude.value && !_noCameraValueRecalc) {
recalcFromCameraValues()
}
}
}
Connections {
target: missionItem
onCameraValueChanged: {
if (gridTypeCombo.currentIndex >= _gridTypeCustomCamera && !_noCameraValueRecalc) {
QGCPalette { id: qgcPal; colorGroupEnabled: true }
id: cameraOrientationGroup
onCurrentChanged: {
if (gridTypeCombo.currentIndex >= _gridTypeCustomCamera) {
recalcFromCameraValues()
}
Column {
id: editorColumn
anchors.margins: _margin
anchors.top: parent.top
anchors.left: parent.left
text: qsTr("Camera")
showSpacer: false
}
anchors.left: parent.left
anchors.right: parent.right
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
spacing: _margin
visible: cameraHeader.checked
QGCComboBox {
id: gridTypeCombo
anchors.left: parent.left
anchors.right: parent.right
model: _cameraList
currentIndex: -1
onActivated: {
if (index == _gridTypeManual) {
missionItem.manualGrid.value = true
} else if (index == _gridTypeCustomCamera) {
missionItem.manualGrid.value = false
missionItem.camera.value = gridTypeCombo.textAt(index)
missionItem.cameraOrientationFixed = false
} else {
missionItem.manualGrid.value = false
missionItem.camera.value = gridTypeCombo.textAt(index)
_noCameraValueRecalc = true
var listIndex = index - _gridTypeCamera
missionItem.cameraSensorWidth.rawValue = _vehicleCameraList[listIndex].sensorWidth
missionItem.cameraSensorHeight.rawValue = _vehicleCameraList[listIndex].sensorHeight
missionItem.cameraResolutionWidth.rawValue = _vehicleCameraList[listIndex].imageWidth
missionItem.cameraResolutionHeight.rawValue = _vehicleCameraList[listIndex].imageHeight
missionItem.cameraFocalLength.rawValue = _vehicleCameraList[listIndex].focalLength
missionItem.cameraOrientationLandscape.rawValue = _vehicleCameraList[listIndex].landscape ? 1 : 0
missionItem.cameraOrientationFixed = _vehicleCameraList[listIndex].fixedOrientation
_noCameraValueRecalc = false
recalcFromCameraValues()
}
}
}
RowLayout {
anchors.left: parent.left
anchors.right: parent.right
spacing: _margin
visible: missionItem.manualGrid.value == true
QGCCheckBox {
id: cameraTriggerDistanceCheckBox
anchors.baseline: cameraTriggerDistanceField.baseline
text: qsTr("Trigger Distance")
checked: missionItem.cameraTriggerDistance.rawValue > 0
onClicked: {
if (checked) {
missionItem.cameraTriggerDistance.value = missionItem.cameraTriggerDistance.defaultValue
} else {
missionItem.cameraTriggerDistance.value = 0
}
}
}
FactTextField {
id: cameraTriggerDistanceField
Layout.fillWidth: true
fact: missionItem.cameraTriggerDistance
enabled: cameraTriggerDistanceCheckBox.checked
text: qsTr("Hover and capture image")
fact: missionItem.hoverAndCapture
visible: missionItem.hoverAndCaptureAllowed
anchors.right: parent.right
spacing: _margin
visible: gridTypeCombo.currentIndex != _gridTypeManual
spacing: _margin
anchors.horizontalCenter: parent.horizontalCenter
visible: !missionItem.cameraOrientationFixed
QGCRadioButton {
width: _editFieldWidth
text: "Landscape"
checked: !!missionItem.cameraOrientationLandscape.value
onClicked: missionItem.cameraOrientationLandscape.value = 1
QGCRadioButton {
id: cameraOrientationPortrait
text: "Portrait"
checked: !missionItem.cameraOrientationLandscape.value
onClicked: missionItem.cameraOrientationLandscape.value = 0
anchors.left: parent.left
anchors.right: parent.right
spacing: _margin
visible: gridTypeCombo.currentIndex === _gridTypeCustomCamera
RowLayout {
anchors.left: parent.left
anchors.right: parent.right
spacing: _margin
Item { Layout.fillWidth: true }
QGCLabel {
Layout.preferredWidth: _root._fieldWidth
text: qsTr("Width")
}
QGCLabel {
Layout.preferredWidth: _root._fieldWidth
text: qsTr("Height")
}
}
RowLayout {
anchors.left: parent.left
anchors.right: parent.right
spacing: _margin
QGCLabel { text: qsTr("Sensor"); Layout.fillWidth: true }
Layout.preferredWidth: _root._fieldWidth
fact: missionItem.cameraSensorWidth
}
FactTextField {
Layout.preferredWidth: _root._fieldWidth
RowLayout {
anchors.left: parent.left
anchors.right: parent.right
spacing: _margin
QGCLabel { text: qsTr("Image"); Layout.fillWidth: true }
Layout.preferredWidth: _root._fieldWidth
fact: missionItem.cameraResolutionWidth
}
FactTextField {
Layout.preferredWidth: _root._fieldWidth
fact: missionItem.cameraResolutionHeight
}
}
RowLayout {
anchors.left: parent.left
anchors.right: parent.right
spacing: _margin
QGCLabel {
Layout.fillWidth: true
}
FactTextField {
Layout.preferredWidth: _root._fieldWidth
fact: missionItem.cameraFocalLength
}
} // Column - custom camera
RowLayout {
anchors.left: parent.left
anchors.right: parent.right
Item { Layout.fillWidth: true }
QGCLabel {
Layout.preferredWidth: _root._fieldWidth
text: qsTr("Frontal")
Layout.preferredWidth: _root._fieldWidth
text: qsTr("Side")
RowLayout {
anchors.left: parent.left
anchors.right: parent.right
spacing: _margin
QGCLabel { text: qsTr("Overlap"); Layout.fillWidth: true }
Layout.preferredWidth: _root._fieldWidth
fact: missionItem.frontalOverlap
Layout.preferredWidth: _root._fieldWidth
fact: missionItem.sideOverlap
SectionHeader {
id: gridHeader
text: qsTr("Grid")
}
anchors.left: parent.left
anchors.right: parent.right
columnSpacing: _margin
rowSpacing: _margin
columns: 2
fact: missionItem.gridAngle
Layout.fillWidth: true
QGCLabel { text: qsTr("Turnaround dist") }
FactTextField {
fact: missionItem.turnaroundDist
QGCCheckBox {
text: qsTr("Refly at 90 degree offset")
checked: missionItem.refly90Degrees
onClicked: missionItem.refly90Degrees = checked
Layout.columnSpan: 2
}
QGCLabel {
wrapMode: Text.WordWrap
font.pointSize: ScreenTools.smallFontPointSize
text: qsTr("Which value would you like to keep constant as you adjust other settings")
Layout.preferredWidth: parent.width
Layout.columnSpan: 2
}
checked: !!missionItem.fixedValueIsAltitude.value
exclusiveGroup: fixedValueGroup
onClicked: missionItem.fixedValueIsAltitude.value = 1
fact: missionItem.gridAltitude
enabled: fixedAltitudeRadio.checked
id: fixedGroundResolutionRadio
checked: !missionItem.fixedValueIsAltitude.value
exclusiveGroup: fixedValueGroup
onClicked: missionItem.fixedValueIsAltitude.value = 0
fact: missionItem.groundResolution
enabled: fixedGroundResolutionRadio.checked
SectionHeader {
id: manualGridHeader
text: qsTr("Grid")
visible: gridTypeCombo.currentIndex == _gridTypeManual
}
anchors.left: parent.left
anchors.right: parent.right
spacing: _margin
visible: manualGridHeader.visible && manualGridHeader.checked
FactTextFieldGrid {
anchors.left: parent.left
anchors.right: parent.right
columnSpacing: ScreenTools.defaultFontPixelWidth
rowSpacing: _margin
factList: [ missionItem.gridAngle, missionItem.gridSpacing, missionItem.gridAltitude, missionItem.turnaroundDist ]
factLabels: [ qsTr("Angle"), qsTr("Spacing"), qsTr("Altitude"), qsTr("Turnaround dist")]
QGCCheckBox {
text: qsTr("Refly at 90 degree offset")
checked: missionItem.refly90Degrees
onClicked: missionItem.refly90Degrees = checked
}
anchors.left: parent.left
text: qsTr("Relative altitude")
fact: missionItem.gridAltitudeRelative
SectionHeader {
id: statsHeader
text: qsTr("Statistics") }
columns: 2
columnSpacing: ScreenTools.defaultFontPixelWidth
QGCLabel { text: QGroundControl.squareMetersToAppSettingsAreaUnits(missionItem.coveredArea).toFixed(2) + " " + QGroundControl.appSettingsAreaUnitsString }
QGCLabel { text: missionItem.cameraShots }
QGCLabel {
text: {
var timeVal = missionItem.timeBetweenShots
if(!isFinite(timeVal) || missionItem.cameraShots === 0) {
return qsTr("N/A")
}
return timeVal.toFixed(1) + " " + qsTr("secs")
}
}