Skip to content

Commit 7a698f2

Browse files
committed
Fixes #17574 Add Z support in AddCircularString map tools
1 parent 45ca0eb commit 7a698f2

File tree

6 files changed

+92
-4
lines changed

6 files changed

+92
-4
lines changed

python/gui/qgsmaptoolcapture.sip.in

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,19 @@ convenient method to clean members
102102

103103
int fetchLayerPoint( const QgsPointLocator::Match &match, QgsPoint &layerPoint );
104104

105+
QgsPoint pointFromPointXY( const QgsPointXY &point ) const;
106+
%Docstring
107+
Creates a QgsPoint with ZM support if necessary (according to the
108+
WkbType of the current layer) from a QgsPointXY.
109+
110+
\param point A QgsPointXY to convert
111+
112+
:return: a point if ZM support if necessary
113+
114+
.. versionadded:: 3.0
115+
:rtype: QgsPoint
116+
%End
117+
105118
int addVertex( const QgsPointXY &point );
106119

107120
int addVertex( const QgsPointXY &mapPoint, const QgsPointLocator::Match &match );

src/app/qgsmaptoolcircularstringcurvepoint.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ QgsMapToolCircularStringCurvePoint::QgsMapToolCircularStringCurvePoint( QgsMapTo
2929

3030
void QgsMapToolCircularStringCurvePoint::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
3131
{
32-
QgsPoint mapPoint( e->mapPoint() );
32+
QgsPoint mapPoint = pointFromPointXY( e->mapPoint() );
3333

3434
if ( e->button() == Qt::LeftButton )
3535
{

src/app/qgsmaptoolcircularstringradius.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ void QgsMapToolCircularStringRadius::deactivate()
4343

4444
void QgsMapToolCircularStringRadius::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
4545
{
46-
QgsPoint mapPoint( e->mapPoint() );
46+
QgsPoint mapPoint = pointFromPointXY( e->mapPoint() );
4747

4848
if ( e->button() == Qt::LeftButton )
4949
{
@@ -55,7 +55,7 @@ void QgsMapToolCircularStringRadius::cadCanvasReleaseEvent( QgsMapMouseEvent *e
5555
{
5656
if ( mPoints.size() % 2 )
5757
{
58-
mTemporaryEndPoint = mapPoint;
58+
mTemporaryEndPoint = pointFromPointXY( mapPoint );
5959

6060
//initial radius is distance( tempPoint - mPoints.last ) / 2.0
6161
double minRadius = std::sqrt( QgsGeometryUtils::sqrDistance2D( mPoints.last(), mTemporaryEndPoint ) ) / 2.0;
@@ -136,7 +136,7 @@ void QgsMapToolCircularStringRadius::recalculateTempRubberBand( const QgsPointXY
136136
else
137137
{
138138
rubberBandPoints.append( mPoints.last() );
139-
rubberBandPoints.append( QgsPoint( mousePosition ) );
139+
rubberBandPoints.append( pointFromPointXY( mousePosition ) );
140140
}
141141
QgsCircularString *cString = new QgsCircularString();
142142
cString->setPoints( rubberBandPoints );

src/core/geometry/qgsgeometryutils.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,24 @@ bool QgsGeometryUtils::segmentMidPoint( const QgsPoint &p1, const QgsPoint &p2,
604604
}
605605

606606
result = possibleMidPoints.at( minDistIndex );
607+
608+
// add z support if necessary
609+
if ( p1.is3D() && p2.is3D() )
610+
{
611+
result.convertTo( p1.wkbType() );
612+
result.setZ( ( p1.z() + p2.z() ) / 2. );
613+
}
614+
else if ( p1.is3D() && !p2.is3D() )
615+
{
616+
result.convertTo( p1.wkbType() );
617+
result.setZ( p1.z() );
618+
}
619+
else if ( !p1.is3D() && p2.is3D() )
620+
{
621+
result.convertTo( p2.wkbType() );
622+
result.setZ( p2.z() );
623+
}
624+
607625
return true;
608626
}
609627

src/gui/qgsmaptoolcapture.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -768,3 +768,48 @@ void QgsMapToolCapture::setPoints( const QVector<QgsPointXY> &pointList )
768768
mSnappingMatches.append( QgsPointLocator::Match() );
769769
}
770770

771+
QgsPoint QgsMapToolCapture::pointFromPointXY( const QgsPointXY &point ) const
772+
{
773+
QgsPoint newPoint( QgsWkbTypes::Point, point.x(), point.y() );
774+
775+
// get current layer
776+
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
777+
if ( !vlayer )
778+
{
779+
return newPoint;
780+
}
781+
782+
// convert to the corresponding type for a full ZM support
783+
QgsWkbTypes::Type type = vlayer->wkbType();
784+
if ( QgsWkbTypes::hasZ( type ) && !QgsWkbTypes::hasM( type ) )
785+
{
786+
newPoint.convertTo( QgsWkbTypes::PointZ );
787+
}
788+
else if ( !QgsWkbTypes::hasZ( type ) && QgsWkbTypes::hasM( type ) )
789+
{
790+
newPoint.convertTo( QgsWkbTypes::PointM );
791+
}
792+
else if ( QgsWkbTypes::hasZ( type ) && QgsWkbTypes::hasM( type ) )
793+
{
794+
newPoint.convertTo( QgsWkbTypes::PointZM );
795+
}
796+
797+
// set default value for Z if necessary
798+
if ( QgsWkbTypes::hasZ( newPoint.wkbType() ) )
799+
newPoint.setZ( defaultZValue() );
800+
801+
return newPoint;
802+
}
803+
804+
#ifdef Q_OS_WIN
805+
bool QgsMapToolCapture::eventFilter( QObject *obj, QEvent *event )
806+
{
807+
if ( event->type() != QEvent::ContextMenu )
808+
return false;
809+
810+
if ( --mSkipNextContextMenuEvent == 0 )
811+
obj->removeEventFilter( this );
812+
813+
return mSkipNextContextMenuEvent >= 0;
814+
}
815+
#endif

src/gui/qgsmaptoolcapture.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,18 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing
147147
// TODO QGIS 3.0 returns an enum instead of a magic constant
148148
int fetchLayerPoint( const QgsPointLocator::Match &match, QgsPoint &layerPoint );
149149

150+
/**
151+
* Creates a QgsPoint with ZM support if necessary (according to the
152+
* WkbType of the current layer) from a QgsPointXY.
153+
*
154+
* \param point A QgsPointXY to convert
155+
*
156+
* \returns a point if ZM support if necessary
157+
*
158+
* \since QGIS 3.0
159+
*/
160+
QgsPoint pointFromPointXY( const QgsPointXY &point ) const;
161+
150162
/**
151163
* Adds a point to the rubber band (in map coordinates) and to the capture list (in layer coordinates)
152164
* \returns 0 in case of success, 1 if current layer is not a vector layer, 2 if coordinate transformation failed

0 commit comments

Comments
 (0)