Skip to content

Commit

Permalink
Fix addFeature and addPart maptool for layers with a Z
Browse files Browse the repository at this point in the history
  • Loading branch information
Hugo Mercier committed Feb 9, 2016
1 parent 2ebd26a commit e2123c7
Show file tree
Hide file tree
Showing 13 changed files with 253 additions and 24 deletions.
8 changes: 8 additions & 0 deletions python/core/geometry/qgsgeometry.sip
Expand Up @@ -291,6 +291,14 @@ class QgsGeometry
*/
int addPart( const QList<QgsPoint> &points, QGis::GeometryType geomType = QGis::UnknownGeometry );

/** Adds a new part to a the geometry.
* @param points points describing part to add
* @param geomType default geometry type to create if no existing geometry
* @returns 0 in case of success, 1 if not a multipolygon, 2 if ring is not a valid geometry, 3 if new polygon ring
* not disjoint with existing polygons of the feature
*/
int addPart( const QList<QgsPointV2> &points, QGis::GeometryType geomType = QGis::UnknownGeometry );

/** Adds a new part to this geometry.
* @param part part to add (ownership is transferred)
* @param geomType default geometry type to create if no existing geometry
Expand Down
45 changes: 43 additions & 2 deletions python/gui/qgsmaptoolcapture.sip
Expand Up @@ -68,8 +68,49 @@ class QgsMapToolCapture : public QgsMapToolAdvancedDigitizing


protected:
int nextPoint( const QgsPoint& mapPoint, QgsPoint& layerPoint );
int nextPoint( QPoint p, QgsPoint &layerPoint, QgsPoint &mapPoint );
/** Converts a map point to layer coordinates
@param mapPoint the point in map coordinates
@param[inout] layerPoint the point in layer coordinates
@return
0 in case of success
1 if the current layer is null or not a vector layer
2 if the transformation failed
@deprecated use nextPoint(const QgsPointV2&, QgsPointV2&)
*/
int nextPoint( const QgsPoint& mapPoint, QgsPoint& layerPoint ) /Deprecated/;

/** Converts a map point to layer coordinates
@param mapPoint the point in map coordinates
@param[inout] layerPoint the point in layer coordinates
@return
0 in case of success
1 if the current layer is null or not a vector layer
2 if the transformation failed
*/
int nextPoint( const QgsPointV2& mapPoint, QgsPointV2& layerPoint );

/** Converts a point to map coordinates and layer coordinates
@param p the input point
@param[inout] layerPoint the point in layer coordinates
@param[inout] mapPoint the point in map coordinates
@return
0 in case of success
1 if the current layer is null or not a vector layer
2 if the transformation failed
@deprecated use nextPoint( const QPoint&, QgsPointV2&, QgsPointV2& )
*/
int nextPoint( QPoint p, QgsPoint &layerPoint, QgsPoint &mapPoint ) /Deprecated/;

/** Converts a point to map coordinates and layer coordinates
@param p the input point
@param[inout] layerPoint the point in layer coordinates
@param[inout] mapPoint the point in map coordinates
@return
0 in case of success
1 if the current layer is null or not a vector layer
2 if the transformation failed
*/
int nextPoint( QPoint p, QgsPointV2 &layerPoint, QgsPointV2 &mapPoint );

/** Adds a point to the rubber band (in map coordinates) and to the capture list (in layer coordinates)
@return 0 in case of success, 1 if current layer is not a vector layer, 2 if coordinate transformation failed*/
Expand Down
15 changes: 13 additions & 2 deletions src/app/qgsmaptooladdfeature.cpp
Expand Up @@ -21,6 +21,7 @@
#include "qgsfield.h"
#include "qgsgeometry.h"
#include "qgslinestringv2.h"
#include "qgsmultipointv2.h"
#include "qgsmapcanvas.h"
#include "qgsmaplayerregistry.h"
#include "qgsmapmouseevent.h"
Expand Down Expand Up @@ -130,14 +131,24 @@ void QgsMapToolAddFeature::cadCanvasReleaseEvent( QgsMapMouseEvent* e )
QgsFeature f( vlayer->fields(), 0 );

QgsGeometry *g = nullptr;
if ( layerWKBType == QGis::WKBPoint || layerWKBType == QGis::WKBPoint25D )
if ( layerWKBType == QGis::WKBPoint )
{
g = QgsGeometry::fromPoint( savePoint );
}
else if ( layerWKBType == QGis::WKBMultiPoint || layerWKBType == QGis::WKBMultiPoint25D )
else if ( layerWKBType == QGis::WKBPoint25D )
{
g = new QgsGeometry( new QgsPointV2( QgsWKBTypes::PointZ, savePoint.x(), savePoint.y(), 0.0 ) );
}
else if ( layerWKBType == QGis::WKBMultiPoint )
{
g = QgsGeometry::fromMultiPoint( QgsMultiPoint() << savePoint );
}
else if ( layerWKBType == QGis::WKBMultiPoint25D )
{
QgsMultiPointV2* mp = new QgsMultiPointV2();
mp->addGeometry( new QgsPointV2( QgsWKBTypes::PointZ, savePoint.x(), savePoint.y(), 0.0 ) );
g = new QgsGeometry( mp );
}
else
{
// if layer supports more types (mCheckGeometryType is false)
Expand Down
6 changes: 3 additions & 3 deletions src/app/qgsmaptooladdpart.cpp
Expand Up @@ -75,17 +75,17 @@ void QgsMapToolAddPart::cadCanvasReleaseEvent( QgsMapMouseEvent * e )
{
case CapturePoint:
{
QgsPoint layerPoint;
QgsPointV2 layerPoint;
QgsPoint mapPoint = e->mapPoint();

if ( nextPoint( mapPoint, layerPoint ) != 0 )
if ( nextPoint( QgsPointV2( mapPoint ), layerPoint ) != 0 )
{
QgsDebugMsg( "nextPoint failed" );
return;
}

vlayer->beginEditCommand( tr( "Part added" ) );
errorCode = vlayer->addPart( QList<QgsPoint>() << layerPoint );
errorCode = vlayer->addPart( QList<QgsPointV2>() << layerPoint );
}
break;

Expand Down
13 changes: 9 additions & 4 deletions src/core/geometry/qgsgeometry.cpp
Expand Up @@ -583,18 +583,23 @@ int QgsGeometry::addRing( QgsCurveV2* ring )
}

int QgsGeometry::addPart( const QList<QgsPoint> &points, QGis::GeometryType geomType )
{
QList<QgsPointV2> l;
convertPointList( points, l );
return addPart( l, geomType );
}

int QgsGeometry::addPart( const QList<QgsPointV2> &points, QGis::GeometryType geomType )
{
QgsAbstractGeometryV2* partGeom = nullptr;
if ( points.size() == 1 )
{
partGeom = new QgsPointV2( points[0].x(), points[0].y() );
partGeom = new QgsPointV2( points[0] );
}
else if ( points.size() > 1 )
{
QgsLineStringV2* ringLine = new QgsLineStringV2();
QList< QgsPointV2 > partPoints;
convertPointList( points, partPoints );
ringLine->setPoints( partPoints );
ringLine->setPoints( points );
partGeom = ringLine;
}
return addPart( partGeom, geomType );
Expand Down
8 changes: 8 additions & 0 deletions src/core/geometry/qgsgeometry.h
Expand Up @@ -335,6 +335,14 @@ class CORE_EXPORT QgsGeometry
*/
int addPart( const QList<QgsPoint> &points, QGis::GeometryType geomType = QGis::UnknownGeometry );

/** Adds a new part to a the geometry.
* @param points points describing part to add
* @param geomType default geometry type to create if no existing geometry
* @returns 0 in case of success, 1 if not a multipolygon, 2 if ring is not a valid geometry, 3 if new polygon ring
* not disjoint with existing polygons of the feature
*/
int addPart( const QList<QgsPointV2> &points, QGis::GeometryType geomType = QGis::UnknownGeometry );

/** Adds a new part to this geometry.
* @param part part to add (ownership is transferred)
* @param geomType default geometry type to create if no existing geometry
Expand Down
22 changes: 22 additions & 0 deletions src/core/qgsvectorlayer.cpp
Expand Up @@ -1155,6 +1155,28 @@ int QgsVectorLayer::addPart( const QList<QgsPoint> &points )
return utils.addPart( points, *mSelectedFeatureIds.constBegin() );
}

int QgsVectorLayer::addPart( const QList<QgsPointV2> &points )
{
if ( !mValid || !mEditBuffer || !mDataProvider )
return 7;

//number of selected features must be 1

if ( mSelectedFeatureIds.size() < 1 )
{
QgsDebugMsg( "Number of selected features <1" );
return 4;
}
else if ( mSelectedFeatureIds.size() > 1 )
{
QgsDebugMsg( "Number of selected features >1" );
return 5;
}

QgsVectorLayerEditUtils utils( this );
return utils.addPart( points, *mSelectedFeatureIds.constBegin() );
}

int QgsVectorLayer::addPart( QgsCurveV2* ring )
{
if ( !mValid || !mEditBuffer || !mDataProvider )
Expand Down
12 changes: 12 additions & 0 deletions src/core/qgsvectorlayer.h
Expand Up @@ -974,6 +974,18 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
7 layer not editable */
int addPart( const QList<QgsPoint>& ring );

/** Adds a new part polygon to a multipart feature
@return
0 in case of success,
1 if selected feature is not multipart,
2 if ring is not a valid geometry,
3 if new polygon ring not disjoint with existing rings,
4 if no feature was selected,
5 if several features are selected,
6 if selected geometry not found
7 layer not editable */
int addPart( const QList<QgsPointV2>& ring );

//! @note available in python as addCurvedPart
int addPart( QgsCurveV2* ring );

Expand Down
10 changes: 10 additions & 0 deletions src/core/qgsvectorlayereditutils.cpp
Expand Up @@ -180,6 +180,16 @@ int QgsVectorLayerEditUtils::addRing( QgsCurveV2* ring, const QgsFeatureIds& tar
}

int QgsVectorLayerEditUtils::addPart( const QList<QgsPoint> &points, QgsFeatureId featureId )
{
QList<QgsPointV2> l;
for ( QList<QgsPoint>::const_iterator it = points.constBegin(); it != points.constEnd(); ++it )
{
l << QgsPointV2( *it );
}
return addPart( l, featureId );
}

int QgsVectorLayerEditUtils::addPart( const QList<QgsPointV2> &points, QgsFeatureId featureId )
{
if ( !L->hasGeometryType() )
return 6;
Expand Down
11 changes: 11 additions & 0 deletions src/core/qgsvectorlayereditutils.h
Expand Up @@ -102,6 +102,17 @@ class CORE_EXPORT QgsVectorLayerEditUtils
6 if selected geometry not found*/
int addPart( const QList<QgsPoint>& ring, QgsFeatureId featureId );

/** Adds a new part polygon to a multipart feature
@return
0 in case of success,
1 if selected feature is not multipart,
2 if ring is not a valid geometry,
3 if new polygon ring not disjoint with existing rings,
4 if no feature was selected,
5 if several features are selected,
6 if selected geometry not found*/
int addPart( const QList<QgsPointV2>& ring, QgsFeatureId featureId );

int addPart( QgsCurveV2* ring, QgsFeatureId featureId );

/** Translates feature by dx, dy
Expand Down
44 changes: 33 additions & 11 deletions src/gui/qgsmaptoolcapture.cpp
Expand Up @@ -214,11 +214,11 @@ bool QgsMapToolCapture::tracingAddVertex( const QgsPoint& point )
bool res = tracer->isPointSnapped( point );
if ( res )
{
QgsPoint layerPoint;
nextPoint( point, layerPoint ); // assuming the transform went fine earlier
QgsPointV2 layerPoint;
nextPoint( QgsPointV2( point ), layerPoint ); // assuming the transform went fine earlier

mRubberBand->addPoint( point );
mCaptureCurve.addVertex( QgsPointV2( layerPoint.x(), layerPoint.y() ) );
mCaptureCurve.addVertex( layerPoint );
}
return res;
}
Expand All @@ -234,12 +234,12 @@ bool QgsMapToolCapture::tracingAddVertex( const QgsPoint& point )

// transform points
QList<QgsPointV2> layerPoints;
QgsPoint lp; // in layer coords
QgsPointV2 lp; // in layer coords
for ( int i = 1; i < points.count(); ++i )
{
if ( nextPoint( points[i], lp ) != 0 )
if ( nextPoint( QgsPointV2( points[i] ), lp ) != 0 )
return false;
layerPoints << QgsPointV2( lp.x(), lp.y() );
layerPoints << lp;
}

for ( int i = 1; i < points.count(); ++i )
Expand Down Expand Up @@ -317,6 +317,16 @@ void QgsMapToolCapture::cadCanvasMoveEvent( QgsMapMouseEvent * e )
} // mouseMoveEvent

int QgsMapToolCapture::nextPoint( const QgsPoint& mapPoint, QgsPoint& layerPoint )
{
QgsPointV2 p1( mapPoint.x(), mapPoint.y() );
QgsPointV2 p2;
int r = nextPoint( p1, p2 );
layerPoint.setX( p2.x() );
layerPoint.setY( p2.y() );
return r;
}

int QgsMapToolCapture::nextPoint( const QgsPointV2& mapPoint, QgsPointV2& layerPoint )
{
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
if ( !vlayer )
Expand All @@ -326,7 +336,12 @@ int QgsMapToolCapture::nextPoint( const QgsPoint& mapPoint, QgsPoint& layerPoint
}
try
{
layerPoint = toLayerCoordinates( vlayer, mapPoint ); //transform snapped point back to layer crs
QgsPoint mapP( mapPoint.x(), mapPoint.y() );
layerPoint = QgsPointV2( toLayerCoordinates( vlayer, mapP ) ); //transform snapped point back to layer crs
if ( QgsWKBTypes::hasZ( QGis::fromOldWkbType( vlayer->wkbType() ) ) )
layerPoint.addZValue( 0.0 );
if ( QgsWKBTypes::hasM( QGis::fromOldWkbType( vlayer->wkbType() ) ) )
layerPoint.addMValue( 0.0 );
}
catch ( QgsCsException &cse )
{
Expand All @@ -338,11 +353,18 @@ int QgsMapToolCapture::nextPoint( const QgsPoint& mapPoint, QgsPoint& layerPoint
return 0;
}

int QgsMapToolCapture::nextPoint( QPoint p, QgsPoint &layerPoint, QgsPoint &mapPoint )
int QgsMapToolCapture::nextPoint( QPoint p, QgsPointV2 &layerPoint, QgsPointV2 &mapPoint )
{
mapPoint = QgsPointV2( toMapCoordinates( p ) );
return nextPoint( mapPoint, layerPoint );
}

int QgsMapToolCapture::nextPoint( QPoint p, QgsPoint &layerPoint, QgsPoint &mapPoint )
{
mapPoint = toMapCoordinates( p );
Q_NOWARN_DEPRECATED_PUSH
return nextPoint( mapPoint, layerPoint );
Q_NOWARN_DEPRECATED_POP
}

int QgsMapToolCapture::addVertex( const QgsPoint& point )
Expand All @@ -354,8 +376,8 @@ int QgsMapToolCapture::addVertex( const QgsPoint& point )
}

int res;
QgsPoint layerPoint;
res = nextPoint( point, layerPoint );
QgsPointV2 layerPoint;
res = nextPoint( QgsPointV2( point ), layerPoint );
if ( res != 0 )
{
return res;
Expand Down Expand Up @@ -385,7 +407,7 @@ int QgsMapToolCapture::addVertex( const QgsPoint& point )
{
// ordinary digitizing
mRubberBand->addPoint( point );
mCaptureCurve.addVertex( QgsPointV2( layerPoint.x(), layerPoint.y() ) );
mCaptureCurve.addVertex( layerPoint );
}

if ( mCaptureMode == CaptureLine )
Expand Down

0 comments on commit e2123c7

Please sign in to comment.