-
-
Notifications
You must be signed in to change notification settings - Fork 228
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: Vertex tool improvement #5797
Changes from 3 commits
ab0f1d0
b11c935
31addf2
2bf1179
c3b8f4f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,6 +32,7 @@ VertexModel::VertexModel( QObject *parent ) | |
connect( this, &VertexModel::vertexCountChanged, this, &VertexModel::updateCanPreviousNextVertex ); | ||
connect( this, &VertexModel::currentVertexIndexChanged, this, &VertexModel::updateCanPreviousNextVertex ); | ||
connect( this, &VertexModel::currentVertexIndexChanged, this, &VertexModel::updateCanRemoveVertex ); | ||
connect( this, &VertexModel::currentVertexIndexChanged, this, &VertexModel::updateAngleFound ); | ||
} | ||
|
||
void VertexModel::setMapSettings( QgsQuickMapSettings *mapSettings ) | ||
|
@@ -562,6 +563,11 @@ void VertexModel::next() | |
} | ||
} | ||
|
||
QgsPoint VertexModel::getPoint( int index ) | ||
{ | ||
return mVertices[index].point; | ||
} | ||
|
||
void VertexModel::addVertexNearestToPosition( const QgsPoint &mapPoint ) | ||
{ | ||
double closestDistance = std::numeric_limits<double>::max(); | ||
|
@@ -685,6 +691,31 @@ QgsPoint VertexModel::currentPoint() const | |
{ | ||
return mVertices.value( mCurrentIndex ).point; | ||
} | ||
// Function to calculate the angle between two vectors | ||
double VertexModel::calculateAngle( const QgsPoint &a, const QgsPoint &b, const QgsPoint &c ) | ||
{ | ||
// Create vectors AB and BC | ||
double AB_x = b.x() - a.x(); | ||
double AB_y = b.y() - a.y(); | ||
double BC_x = c.x() - b.x(); | ||
double BC_y = c.y() - b.y(); | ||
|
||
// Calculate dot product | ||
double dotProduct = AB_x * BC_x + AB_y * BC_y; | ||
|
||
// Calculate magnitudes | ||
double magnitudeAB = std::sqrt( AB_x * AB_x + AB_y * AB_y ); | ||
double magnitudeBC = std::sqrt( BC_x * BC_x + BC_y * BC_y ); | ||
|
||
// Calculate cosine of the angle | ||
double cosTheta = dotProduct / ( magnitudeAB * magnitudeBC ); | ||
|
||
// Calculate the angle in radians | ||
double angle = std::acos( cosTheta ); | ||
|
||
// Convert to degrees | ||
return std::abs( angle * ( 180.0 / M_PI ) - 180 ); | ||
} | ||
|
||
void VertexModel::setCurrentPoint( const QgsPoint &point ) | ||
{ | ||
|
@@ -696,6 +727,25 @@ void VertexModel::setCurrentPoint( const QgsPoint &point ) | |
|
||
Vertex &vertex = mVertices[mCurrentIndex]; | ||
|
||
// Calculate angles between edges | ||
|
||
int startPoint = mCurrentIndex - 2; | ||
if ( startPoint < 0 ) | ||
{ | ||
startPoint = vertexCount() + startPoint; | ||
} | ||
int endPoint = mCurrentIndex + 2; | ||
if ( endPoint >= vertexCount() ) | ||
{ | ||
endPoint = endPoint - vertexCount(); | ||
} | ||
|
||
double angle = calculateAngle( mVertices[startPoint].point, mVertices[mCurrentIndex].point, mVertices[endPoint].point ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Alright, as discussed yesterday, here I think we shouldn't calculate the angle but rather the point location of the point that'd form the angle we're looking for. Then, we will snap to that point whenever we are close to it. |
||
|
||
qDebug() << "--------- angle = " << angle; | ||
|
||
setAngleFonud( angle > snapToCommonAngleDegrees() - 1 && angle < snapToCommonAngleDegrees() + 1 ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We discussed this yesterday. This wouldn't really work as a/ we wouldn't get a perfect coordinate snapped to angle in any case, and b/ we'd allow for angle 89 and 91 😱 😉 |
||
|
||
if ( mMapSettings && vertex.point.distance( point ) / mMapSettings->mapSettings().mapUnitsPerPixel() < 1 ) | ||
return; | ||
|
||
|
@@ -799,6 +849,11 @@ bool VertexModel::dirty() const | |
return mDirty; | ||
} | ||
|
||
bool VertexModel::angleFonud() const | ||
{ | ||
return mAngleFonud; | ||
} | ||
|
||
bool VertexModel::canRemoveVertex() | ||
{ | ||
return mCanRemoveVertex; | ||
|
@@ -881,6 +936,15 @@ void VertexModel::setDirty( bool dirty ) | |
emit dirtyChanged(); | ||
} | ||
|
||
void VertexModel::setAngleFonud( bool angleFonud ) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This becomes a int commented int he header. But also, keep the getter and setter functions together in the source code (ATM they are disjointed and it just makes the code harder to skim through). |
||
{ | ||
if ( mAngleFonud == angleFonud ) | ||
return; | ||
|
||
mAngleFonud = angleFonud; | ||
emit angleFonudChanged(); | ||
} | ||
|
||
void VertexModel::updateCanRemoveVertex() | ||
{ | ||
bool canRemoveVertex = false; | ||
|
@@ -1032,3 +1096,24 @@ void VertexModel::setEditingMode( VertexModel::EditingMode mode ) | |
|
||
emit editingModeChanged(); | ||
} | ||
|
||
void VertexModel::updateAngleFound() | ||
{ | ||
if ( currentVertexIndex() == -1 ) | ||
{ | ||
setAngleFonud( false ); | ||
} | ||
} | ||
|
||
int VertexModel::snapToCommonAngleDegrees() const | ||
{ | ||
return mSnapToCommonAngleDegrees; | ||
} | ||
|
||
void VertexModel::setSnapToCommonAngleDegrees( int snapToCommonAngleDegrees ) | ||
{ | ||
if ( mSnapToCommonAngleDegrees == snapToCommonAngleDegrees ) | ||
return; | ||
mSnapToCommonAngleDegrees = snapToCommonAngleDegrees; | ||
emit snapToCommonAngleDegreesChanged(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -49,6 +49,9 @@ class QFIELD_CORE_EXPORT VertexModel : public QAbstractListModel | |
Q_PROPERTY( int ringCount READ ringCount NOTIFY ringCountChanged ) | ||
//! determines if the model has changes | ||
Q_PROPERTY( bool dirty READ dirty NOTIFY dirtyChanged ) | ||
|
||
Q_PROPERTY( bool angleFonud READ angleFonud NOTIFY angleFonudChanged ) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As discussed, this should be an int property called snappedAngle. Also, don't forget documentation. |
||
|
||
//! determines if the model allows editing the geometry | ||
Q_PROPERTY( bool editingAllowed READ editingAllowed ) | ||
//! determines if one can remove current vertex | ||
|
@@ -70,6 +73,9 @@ class QFIELD_CORE_EXPORT VertexModel : public QAbstractListModel | |
*/ | ||
Q_PROPERTY( int currentVertexIndex READ currentVertexIndex WRITE setCurrentVertexIndex NOTIFY currentVertexIndexChanged ) | ||
|
||
Q_PROPERTY( int snapToCommonAngleDegrees READ snapToCommonAngleDegrees WRITE setSnapToCommonAngleDegrees NOTIFY snapToCommonAngleDegreesChanged ) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Documentation |
||
|
||
|
||
/** | ||
* The geometry in layer coordinates | ||
*/ | ||
|
@@ -187,6 +193,8 @@ class QFIELD_CORE_EXPORT VertexModel : public QAbstractListModel | |
//! next vertex or segment | ||
Q_INVOKABLE void next(); | ||
|
||
Q_INVOKABLE QgsPoint getPoint( int index ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need to expose this to QML? Should it be a private function? |
||
|
||
//! Selects the vertex at the given screen \a point within a given \a threshold | ||
Q_INVOKABLE void selectVertexAtPosition( const QPointF &point, double threshold, bool autoInsert = true ); | ||
|
||
|
@@ -223,6 +231,7 @@ class QFIELD_CORE_EXPORT VertexModel : public QAbstractListModel | |
|
||
//! \copydoc dirty | ||
bool dirty() const; | ||
bool angleFonud() const; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Documentation |
||
|
||
//! \copydoc canRemoveVertex | ||
bool canRemoveVertex(); | ||
|
@@ -265,6 +274,10 @@ class QFIELD_CORE_EXPORT VertexModel : public QAbstractListModel | |
|
||
bool canUndo(); | ||
|
||
double calculateAngle( const QgsPoint &a, const QgsPoint &b, const QgsPoint &c ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we still use this function, let's move it to GeometryUtils |
||
int snapToCommonAngleDegrees() const; | ||
void setSnapToCommonAngleDegrees( int snapToCommonAngleDegrees ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Documentaton |
||
|
||
signals: | ||
//! \copydoc editingMode | ||
void editingModeChanged(); | ||
|
@@ -278,6 +291,7 @@ class QFIELD_CORE_EXPORT VertexModel : public QAbstractListModel | |
void ringCountChanged(); | ||
//! \copydoc dirty | ||
void dirtyChanged(); | ||
void angleFonudChanged(); | ||
//! \copydoc canRemoveVertex | ||
void canRemoveVertexChanged(); | ||
//! \copydoc canAddVertex | ||
|
@@ -301,15 +315,19 @@ class QFIELD_CORE_EXPORT VertexModel : public QAbstractListModel | |
//! Emitted when the history has been modified | ||
void historyChanged(); | ||
|
||
void snapToCommonAngleDegreesChanged(); | ||
|
||
private: | ||
void refreshGeometry(); | ||
//! Add the candidates of new vertices (extending or segment) | ||
//! This will not emit the reset signals, it's up to the caller to do so | ||
void createCandidates(); | ||
void setDirty( bool dirty ); | ||
void setAngleFonud( bool angleFonud ); | ||
void updateCanRemoveVertex(); | ||
void updateCanAddVertex(); | ||
void updateCanPreviousNextVertex(); | ||
void updateAngleFound(); | ||
void setGeometryType( const Qgis::GeometryType &geometryType ); | ||
|
||
QList<Vertex> mVertices; | ||
|
@@ -322,6 +340,7 @@ class QFIELD_CORE_EXPORT VertexModel : public QAbstractListModel | |
QgsCoordinateTransform mTransform = QgsCoordinateTransform(); | ||
bool mIsMulti = false; | ||
bool mDirty = false; | ||
bool mAngleFonud = false; | ||
|
||
QVector<QgsPoint> mVerticesDeleted; | ||
|
||
|
@@ -350,6 +369,7 @@ class QFIELD_CORE_EXPORT VertexModel : public QAbstractListModel | |
bool mHistoryTraversing = false; | ||
|
||
friend class VertexModelTest; | ||
int mSnapToCommonAngleDegrees; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Keep the friend class line at the very bottom of the class definition, and make sure you initialize your members (i.e. in this case int mSnapToCommonAngleDegrees = 0; |
||
}; | ||
|
||
Q_DECLARE_METATYPE( VertexModel::Vertex ); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI, we don't add comments above functions, we document in the .h[eader] :)