mirror of
https://github.com/qgis/QGIS.git
synced 2025-03-04 00:30:59 -05:00
[FEATURE] Add z distance (#31451)
* Add z-distance in 3d measurement tool. * Refactor code for adding new item in 3d measurement tool. * Fix right click stop the measurement but not reset the table. * Add horisontal distance. * Remove unit in the header. * Add widgets for 3d measurement tool * Calculate total horisontal distance. * Refactor showing total distance. * Handle check box behaviours. * Save state of the checkboxes. * Rename variable for consistency. * Set proper title for 3d measurement tool. * horisontal to horizontal. * use one extra distance. * Remove checkbox for other distance.
This commit is contained in:
parent
a04354c42b
commit
85caa70e76
@ -159,6 +159,7 @@ void Qgs3DMapToolMeasureLine::handleClick( Qt3DRender::QPickEvent *event, const
|
||||
{
|
||||
// Finish measurement
|
||||
mDone = true;
|
||||
restart();
|
||||
}
|
||||
else if ( event->button() == Qt3DRender::QPickEvent::MiddleButton )
|
||||
{
|
||||
@ -239,6 +240,7 @@ void Qgs3DMapToolMeasureLine::restart()
|
||||
mPoints.clear();
|
||||
mDone = true;
|
||||
updateMeasurementLayer();
|
||||
mDialog->resetTable();
|
||||
}
|
||||
|
||||
void Qgs3DMapToolMeasureLine::undo()
|
||||
|
@ -30,6 +30,8 @@ Qgs3DMeasureDialog::Qgs3DMeasureDialog( Qgs3DMapToolMeasureLine *tool, Qt::Windo
|
||||
{
|
||||
setupUi( this );
|
||||
|
||||
setWindowTitle( tr( " 3D Measurement Tool" ) );
|
||||
|
||||
// New button
|
||||
QPushButton *newButton = new QPushButton( tr( "&New" ) );
|
||||
buttonBox->addButton( newButton, QDialogButtonBox::ActionRole );
|
||||
@ -43,6 +45,9 @@ Qgs3DMeasureDialog::Qgs3DMeasureDialog( Qgs3DMapToolMeasureLine *tool, Qt::Windo
|
||||
mEllipsoidal->hide();
|
||||
groupBox->hide();
|
||||
|
||||
// Update text for 3D specific
|
||||
totalDistanceLabel->setText( tr( "Total 3D Distance" ) );
|
||||
|
||||
// Initialize unit combo box
|
||||
// Add a configuration button
|
||||
QPushButton *cb = new QPushButton( tr( "&Configuration" ) );
|
||||
@ -82,20 +87,15 @@ void Qgs3DMeasureDialog::addPoint()
|
||||
if ( !mTool->done() )
|
||||
{
|
||||
// Add new entry in the table
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem( QStringList( QLocale().toString( 0.0, 'f', mDecimalPlaces ) ) );
|
||||
item->setTextAlignment( 0, Qt::AlignRight );
|
||||
mTable->addTopLevelItem( item );
|
||||
mTable->scrollToItem( item );
|
||||
|
||||
item->setText( 0, QString::number( convertLength( lastDistance(), mDisplayedDistanceUnit ) ) );
|
||||
addMeasurement( lastDistance(), lastVerticalDistance(), lastHorizontalDistance() );
|
||||
mTotal += lastDistance();
|
||||
editTotal->setText( formatDistance( convertLength( mTotal, mDisplayedDistanceUnit ) ) );
|
||||
mHorizontalTotal += lastHorizontalDistance();
|
||||
updateTotal();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Update total with new displayed unit
|
||||
editTotal->setText( formatDistance( convertLength( mTotal, mDisplayedDistanceUnit ) ) );
|
||||
updateTotal();
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,6 +106,20 @@ double Qgs3DMeasureDialog::lastDistance()
|
||||
return lastPoint.distance3D( secondLastPoint );
|
||||
}
|
||||
|
||||
double Qgs3DMeasureDialog::lastVerticalDistance()
|
||||
{
|
||||
QgsPoint lastPoint = mTool->points().rbegin()[0];
|
||||
QgsPoint secondLastPoint = mTool->points().rbegin()[1];
|
||||
return lastPoint.z() - secondLastPoint.z();
|
||||
}
|
||||
|
||||
double Qgs3DMeasureDialog::lastHorizontalDistance()
|
||||
{
|
||||
QgsPoint lastPoint = mTool->points().rbegin()[0];
|
||||
QgsPoint secondLastPoint = mTool->points().rbegin()[1];
|
||||
return lastPoint.distance( secondLastPoint );
|
||||
}
|
||||
|
||||
void Qgs3DMeasureDialog::repopulateComboBoxUnits()
|
||||
{
|
||||
mUnitsCombo->addItem( QgsUnitTypes::toString( QgsUnitTypes::DistanceMeters ), QgsUnitTypes::DistanceMeters );
|
||||
@ -130,8 +144,8 @@ void Qgs3DMeasureDialog::removeLastPoint()
|
||||
// Update total distance
|
||||
QgsLineString measureLine( mTool->points() );
|
||||
mTotal = measureLine.length3D();
|
||||
// Update total with new displayed unit
|
||||
editTotal->setText( formatDistance( convertLength( mTotal, mDisplayedDistanceUnit ) ) );
|
||||
mHorizontalTotal = measureLine.length();
|
||||
updateTotal();
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,11 +159,7 @@ void Qgs3DMeasureDialog::reject()
|
||||
void Qgs3DMeasureDialog::restart()
|
||||
{
|
||||
mTool->restart();
|
||||
|
||||
mTable->clear();
|
||||
mTotal = 0.;
|
||||
// Update total with new displayed unit
|
||||
editTotal->setText( formatDistance( convertLength( mTotal, mDisplayedDistanceUnit ) ) );
|
||||
resetTable();
|
||||
}
|
||||
|
||||
void Qgs3DMeasureDialog::closeEvent( QCloseEvent *e )
|
||||
@ -167,41 +177,15 @@ void Qgs3DMeasureDialog::updateSettings()
|
||||
mDisplayedDistanceUnit = QgsUnitTypes::decodeDistanceUnit(
|
||||
settings.value( QStringLiteral( "qgis/measure/displayunits" ),
|
||||
QgsUnitTypes::encodeUnit( QgsUnitTypes::DistanceUnknownUnit ) ).toString() );
|
||||
mTable->setHeaderLabels( QStringList( tr( "Segments [%1]" ).arg( QgsUnitTypes::toString( mDisplayedDistanceUnit ) ) ) );
|
||||
// Choose unit in the combobox
|
||||
setupTableHeader();
|
||||
mUnitsCombo->setCurrentIndex( mUnitsCombo->findData( mDisplayedDistanceUnit ) );
|
||||
}
|
||||
|
||||
void Qgs3DMeasureDialog::unitsChanged( int index )
|
||||
{
|
||||
mDisplayedDistanceUnit = static_cast< QgsUnitTypes::DistanceUnit >( mUnitsCombo->itemData( index ).toInt() );
|
||||
// Set the table header to show displayed unit
|
||||
mTable->setHeaderLabels( QStringList( tr( "Segments [%1]" ).arg( QgsUnitTypes::toString( mDisplayedDistanceUnit ) ) ) );
|
||||
|
||||
// Reset table
|
||||
mTable->clear();
|
||||
|
||||
// Repopulate the table based on new displayed unit
|
||||
QVector<QgsPoint>::const_iterator it;
|
||||
bool isFirstPoint = true; // first point
|
||||
QgsPoint p1, p2;
|
||||
QVector< QgsPoint > tmpPoints = mTool->points();
|
||||
for ( it = tmpPoints.constBegin(); it != tmpPoints.constEnd(); ++it )
|
||||
{
|
||||
p2 = *it;
|
||||
if ( !isFirstPoint )
|
||||
{
|
||||
double distance = p1.distance3D( p2 );
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem( QStringList( QLocale().toString( convertLength( distance, mDisplayedDistanceUnit ), 'f', mDecimalPlaces ) ) );
|
||||
item->setTextAlignment( 0, Qt::AlignRight );
|
||||
mTable->addTopLevelItem( item );
|
||||
mTable->scrollToItem( item );
|
||||
}
|
||||
p1 = p2;
|
||||
isFirstPoint = false;
|
||||
}
|
||||
// Update total with new displayed unit
|
||||
editTotal->setText( formatDistance( convertLength( mTotal, mDisplayedDistanceUnit ) ) );
|
||||
updateTable();
|
||||
updateTotal();
|
||||
}
|
||||
|
||||
double Qgs3DMeasureDialog::convertLength( double length, QgsUnitTypes::DistanceUnit toUnit ) const
|
||||
@ -226,3 +210,80 @@ void Qgs3DMeasureDialog::openConfigTab()
|
||||
{
|
||||
QgisApp::instance()->showOptionsDialog( this, QStringLiteral( "mOptionsPageMapTools" ) );
|
||||
}
|
||||
|
||||
void Qgs3DMeasureDialog::setupTableHeader()
|
||||
{
|
||||
// Set the table header to show displayed unit
|
||||
QStringList headers;
|
||||
headers << tr( "Horizontal Distance" );
|
||||
headers << tr( "Vertical Distance" );
|
||||
headers << tr( "3D Distance" );
|
||||
|
||||
QTreeWidgetItem *headerItem = new QTreeWidgetItem( headers );
|
||||
for ( int i = 0; i < headers.count(); ++i )
|
||||
{
|
||||
headerItem->setTextAlignment( i, Qt::AlignRight );
|
||||
}
|
||||
mTable->setHeaderItem( headerItem );
|
||||
for ( int i = 0; i < headers.count(); ++i )
|
||||
{
|
||||
mTable->resizeColumnToContents( i );
|
||||
}
|
||||
}
|
||||
|
||||
void Qgs3DMeasureDialog::addMeasurement( double distance, double verticalDistance, double horizontalDistance )
|
||||
{
|
||||
QStringList content;
|
||||
content << QLocale().toString( convertLength( horizontalDistance, mDisplayedDistanceUnit ), 'f', mDecimalPlaces );
|
||||
content << QLocale().toString( convertLength( verticalDistance, mDisplayedDistanceUnit ), 'f', mDecimalPlaces );
|
||||
content << QLocale().toString( convertLength( distance, mDisplayedDistanceUnit ), 'f', mDecimalPlaces );
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem( content );
|
||||
for ( int i = 0; i < content.count(); ++i )
|
||||
{
|
||||
item->setTextAlignment( i, Qt::AlignRight );
|
||||
}
|
||||
mTable->addTopLevelItem( item );
|
||||
mTable->scrollToItem( item );
|
||||
}
|
||||
|
||||
void Qgs3DMeasureDialog::updateTotal()
|
||||
{
|
||||
// Update total with new displayed unit
|
||||
editTotal->setText( formatDistance( convertLength( mTotal, mDisplayedDistanceUnit ) ) );
|
||||
editHorizontalTotal->setText( formatDistance( convertLength( mHorizontalTotal, mDisplayedDistanceUnit ) ) );
|
||||
}
|
||||
|
||||
void Qgs3DMeasureDialog::updateTable()
|
||||
{
|
||||
setupTableHeader();
|
||||
|
||||
// Reset table
|
||||
mTable->clear();
|
||||
|
||||
// Repopulate the table based on new displayed unit
|
||||
QVector<QgsPoint>::const_iterator it;
|
||||
bool isFirstPoint = true; // first point
|
||||
QgsPoint p1, p2;
|
||||
QVector< QgsPoint > tmpPoints = mTool->points();
|
||||
for ( it = tmpPoints.constBegin(); it != tmpPoints.constEnd(); ++it )
|
||||
{
|
||||
p2 = *it;
|
||||
if ( !isFirstPoint )
|
||||
{
|
||||
double distance = p1.distance3D( p2 );
|
||||
double verticalDistance = p2.z() - p1.z();
|
||||
double horizontalDistance = p1.distance( p2 );
|
||||
addMeasurement( distance, verticalDistance, horizontalDistance );
|
||||
}
|
||||
p1 = p2;
|
||||
isFirstPoint = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Qgs3DMeasureDialog::resetTable()
|
||||
{
|
||||
mTable->clear();
|
||||
mTotal = 0.;
|
||||
mHorizontalTotal = 0.;
|
||||
updateTotal();
|
||||
}
|
||||
|
@ -45,12 +45,21 @@ class Qgs3DMeasureDialog : public QDialog, private Ui::QgsMeasureBase
|
||||
//! Get last distance in map distance unit
|
||||
double lastDistance();
|
||||
|
||||
//! Get last Z value distance in map distance unit
|
||||
double lastVerticalDistance();
|
||||
|
||||
//! Get last horizontal value distance in map distance unit
|
||||
double lastHorizontalDistance();
|
||||
|
||||
//! Populating unit combo box
|
||||
void repopulateComboBoxUnits();
|
||||
|
||||
//! Remove last point
|
||||
void removeLastPoint();
|
||||
|
||||
// Clear the content of the table
|
||||
void resetTable();
|
||||
|
||||
public slots:
|
||||
void reject() override;
|
||||
|
||||
@ -71,6 +80,9 @@ class Qgs3DMeasureDialog : public QDialog, private Ui::QgsMeasureBase
|
||||
//! Total length in map distance unit
|
||||
double mTotal = 0.0;
|
||||
|
||||
//! Total horizontal length in map distance unit
|
||||
double mHorizontalTotal = 0.0;
|
||||
|
||||
//! Number of decimal places we want.
|
||||
int mDecimalPlaces = 3;
|
||||
|
||||
@ -91,6 +103,18 @@ class Qgs3DMeasureDialog : public QDialog, private Ui::QgsMeasureBase
|
||||
|
||||
//! Open configuration tab
|
||||
void openConfigTab();
|
||||
|
||||
//! Setup the header of the table
|
||||
void setupTableHeader();
|
||||
|
||||
//! Add measurement (3d-distance, vertical distance, horizontal distance) to the table
|
||||
void addMeasurement( double distance, double verticalDistance, double horizontalDistance );
|
||||
|
||||
//! Update total value
|
||||
void updateTotal();
|
||||
|
||||
//! Update table based on current setting
|
||||
void updateTable();
|
||||
};
|
||||
|
||||
#endif // QGS3DMEASUREDIALOG_H
|
||||
|
@ -42,6 +42,10 @@ QgsMeasureDialog::QgsMeasureDialog( QgsMeasureTool *tool, Qt::WindowFlags f )
|
||||
QgsGui::instance()->enableAutoGeometryRestore( this );
|
||||
connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsMeasureDialog::showHelp );
|
||||
|
||||
// hide 3D related options
|
||||
editHorizontalTotal->hide();
|
||||
totalHorizontalDistanceLabel->hide();
|
||||
|
||||
QPushButton *nb = new QPushButton( tr( "&New" ) );
|
||||
buttonBox->addButton( nb, QDialogButtonBox::ActionRole );
|
||||
connect( nb, &QAbstractButton::clicked, this, &QgsMeasureDialog::restart );
|
||||
|
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>359</width>
|
||||
<height>301</height>
|
||||
<width>462</width>
|
||||
<height>376</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="baseSize">
|
||||
@ -39,51 +39,6 @@
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="textLabel2">
|
||||
<property name="text">
|
||||
<string>Total</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>editTotal</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QLineEdit" name="editTotal">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>41</width>
|
||||
<height>25</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="4" column="3">
|
||||
<widget class="QComboBox" name="mUnitsCombo"/>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="4">
|
||||
<widget class="QTreeWidget" name="mTable">
|
||||
<property name="editTriggers">
|
||||
@ -105,27 +60,76 @@
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0" colspan="4">
|
||||
<spacer name="mSpacer">
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="totalDistanceLabel">
|
||||
<property name="text">
|
||||
<string>Total</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>editTotal</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
<width>41</width>
|
||||
<height>25</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="8" column="0" colspan="4">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close|QDialogButtonBox::Help</set>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="totalHorizontalDistanceLabel">
|
||||
<property name="text">
|
||||
<string>Total Horizontal Distance</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0" colspan="4">
|
||||
<item row="6" column="2">
|
||||
<widget class="QLineEdit" name="editHorizontalTotal">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="2">
|
||||
<widget class="QRadioButton" name="mEllipsoidal">
|
||||
<property name="text">
|
||||
<string>Ellipsoidal</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QRadioButton" name="mCartesian">
|
||||
<property name="text">
|
||||
<string>Cartesian</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0" colspan="4">
|
||||
<widget class="QgsCollapsibleGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Info</string>
|
||||
@ -144,26 +148,45 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QRadioButton" name="mCartesian">
|
||||
<property name="text">
|
||||
<string>Cartesian</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
<item row="4" column="3">
|
||||
<widget class="QComboBox" name="mUnitsCombo"/>
|
||||
</item>
|
||||
<item row="11" column="0" colspan="4">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close|QDialogButtonBox::Help</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QRadioButton" name="mEllipsoidal">
|
||||
<property name="text">
|
||||
<string>Ellipsoidal</string>
|
||||
<item row="4" column="2">
|
||||
<widget class="QLineEdit" name="editTotal">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0" colspan="4">
|
||||
<spacer name="mSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
|
Loading…
x
Reference in New Issue
Block a user