Skip to content

Commit

Permalink
[FEATURE] Add z distance (#31451)
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
ismailsunni authored and wonder-sk committed Oct 29, 2019
1 parent a04354c commit 85caa70
Show file tree
Hide file tree
Showing 5 changed files with 223 additions and 109 deletions.
2 changes: 2 additions & 0 deletions src/app/3d/qgs3dmaptoolmeasureline.cpp
Expand Up @@ -159,6 +159,7 @@ void Qgs3DMapToolMeasureLine::handleClick( Qt3DRender::QPickEvent *event, const
{
// Finish measurement
mDone = true;
restart();
}
else if ( event->button() == Qt3DRender::QPickEvent::MiddleButton )
{
Expand Down Expand Up @@ -239,6 +240,7 @@ void Qgs3DMapToolMeasureLine::restart()
mPoints.clear();
mDone = true;
updateMeasurementLayer();
mDialog->resetTable();
}

void Qgs3DMapToolMeasureLine::undo()
Expand Down
151 changes: 106 additions & 45 deletions src/app/3d/qgs3dmeasuredialog.cpp
Expand Up @@ -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 );
Expand All @@ -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" ) );
Expand Down Expand Up @@ -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();
}
}

Expand All @@ -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 );
Expand All @@ -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();
}
}

Expand All @@ -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 )
Expand All @@ -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
Expand All @@ -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();
}
24 changes: 24 additions & 0 deletions src/app/3d/qgs3dmeasuredialog.h
Expand Up @@ -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;

Expand All @@ -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;

Expand All @@ -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
4 changes: 4 additions & 0 deletions src/app/qgsmeasuredialog.cpp
Expand Up @@ -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 );
Expand Down

0 comments on commit 85caa70

Please sign in to comment.