mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
Merge pull request #2268 from mhugent/curve_capture_tool
Curve capture tool
This commit is contained in:
commit
5807875797
@ -508,6 +508,8 @@
|
|||||||
<file>themes/default/mIconClear.png</file>
|
<file>themes/default/mIconClear.png</file>
|
||||||
<file>flags/zh.png</file>
|
<file>flags/zh.png</file>
|
||||||
<file>themes/default/mIconPaintEffects.svg</file>
|
<file>themes/default/mIconPaintEffects.svg</file>
|
||||||
|
<file>themes/default/mActionCircularStringCurvePoint.png</file>
|
||||||
|
<file>themes/default/mActionCircularStringRadius.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
<qresource prefix="/images/tips">
|
<qresource prefix="/images/tips">
|
||||||
<file alias="symbol_levels.png">qgis_tips/symbol_levels.png</file>
|
<file alias="symbol_levels.png">qgis_tips/symbol_levels.png</file>
|
||||||
|
BIN
images/themes/default/mActionCircularStringCurvePoint.png
Normal file
BIN
images/themes/default/mActionCircularStringCurvePoint.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 979 B |
BIN
images/themes/default/mActionCircularStringRadius.png
Normal file
BIN
images/themes/default/mActionCircularStringRadius.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
@ -90,7 +90,7 @@ class QgsAbstractGeometryV2
|
|||||||
virtual QgsRectangle calculateBoundingBox() const;
|
virtual QgsRectangle calculateBoundingBox() const;
|
||||||
|
|
||||||
//render pipeline
|
//render pipeline
|
||||||
virtual void transform( const QgsCoordinateTransform& ct ) = 0;
|
virtual void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform ) = 0;
|
||||||
virtual void transform( const QTransform& t ) = 0;
|
virtual void transform( const QTransform& t ) = 0;
|
||||||
//virtual void clip( const QgsRectangle& rect );
|
//virtual void clip( const QgsRectangle& rect );
|
||||||
virtual void draw( QPainter& p ) const = 0;
|
virtual void draw( QPainter& p ) const = 0;
|
||||||
|
@ -38,7 +38,7 @@ class QgsCircularStringV2: public QgsCurveV2
|
|||||||
virtual QgsLineStringV2* curveToLine() const;
|
virtual QgsLineStringV2* curveToLine() const;
|
||||||
|
|
||||||
void draw( QPainter& p ) const;
|
void draw( QPainter& p ) const;
|
||||||
void transform( const QgsCoordinateTransform& ct );
|
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform );
|
||||||
void transform( const QTransform& t );
|
void transform( const QTransform& t );
|
||||||
//void clip( const QgsRectangle& rect );
|
//void clip( const QgsRectangle& rect );
|
||||||
void addToPainterPath( QPainterPath& path ) const;
|
void addToPainterPath( QPainterPath& path ) const;
|
||||||
|
@ -45,7 +45,7 @@ class QgsCompoundCurveV2: public QgsCurveV2
|
|||||||
void close();
|
void close();
|
||||||
|
|
||||||
void draw( QPainter& p ) const;
|
void draw( QPainter& p ) const;
|
||||||
void transform( const QgsCoordinateTransform& ct );
|
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform );
|
||||||
void transform( const QTransform& t );
|
void transform( const QTransform& t );
|
||||||
void addToPainterPath( QPainterPath& path ) const;
|
void addToPainterPath( QPainterPath& path ) const;
|
||||||
void drawAsPolygon( QPainter& p ) const;
|
void drawAsPolygon( QPainter& p ) const;
|
||||||
|
@ -49,7 +49,7 @@ class QgsCurvePolygonV2: public QgsSurfaceV2
|
|||||||
bool removeInteriorRing( int nr );
|
bool removeInteriorRing( int nr );
|
||||||
|
|
||||||
virtual void draw( QPainter& p ) const;
|
virtual void draw( QPainter& p ) const;
|
||||||
void transform( const QgsCoordinateTransform& ct );
|
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform );
|
||||||
void transform( const QTransform& t );
|
void transform( const QTransform& t );
|
||||||
|
|
||||||
virtual bool insertVertex( const QgsVertexId& position, const QgsPointV2& vertex );
|
virtual bool insertVertex( const QgsVertexId& position, const QgsPointV2& vertex );
|
||||||
|
@ -23,7 +23,7 @@ class QgsGeometryCollectionV2: public QgsAbstractGeometryV2
|
|||||||
virtual bool addGeometry( QgsAbstractGeometryV2* g /Transfer/ );
|
virtual bool addGeometry( QgsAbstractGeometryV2* g /Transfer/ );
|
||||||
virtual bool removeGeometry( int nr );
|
virtual bool removeGeometry( int nr );
|
||||||
|
|
||||||
virtual void transform( const QgsCoordinateTransform& ct );
|
virtual void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform );
|
||||||
void transform( const QTransform& t );
|
void transform( const QTransform& t );
|
||||||
//virtual void clip( const QgsRectangle& rect );
|
//virtual void clip( const QgsRectangle& rect );
|
||||||
virtual void draw( QPainter& p ) const;
|
virtual void draw( QPainter& p ) const;
|
||||||
|
@ -38,7 +38,7 @@ class QgsLineStringV2: public QgsCurveV2
|
|||||||
void append( const QgsLineStringV2* line );
|
void append( const QgsLineStringV2* line );
|
||||||
|
|
||||||
void draw( QPainter& p ) const;
|
void draw( QPainter& p ) const;
|
||||||
void transform( const QgsCoordinateTransform& ct );
|
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform );
|
||||||
void transform( const QTransform& t );
|
void transform( const QTransform& t );
|
||||||
|
|
||||||
void addToPainterPath( QPainterPath& path ) const;
|
void addToPainterPath( QPainterPath& path ) const;
|
||||||
|
@ -119,6 +119,9 @@ SET(QGIS_APP_SRCS
|
|||||||
qgsvectorlayerproperties.cpp
|
qgsvectorlayerproperties.cpp
|
||||||
qgsvisibilitypresets.cpp
|
qgsvisibilitypresets.cpp
|
||||||
qgshandlebadlayers.cpp
|
qgshandlebadlayers.cpp
|
||||||
|
qgsmaptooladdcircularstring.cpp
|
||||||
|
qgsmaptoolcircularstringcurvepoint.cpp
|
||||||
|
qgsmaptoolcircularstringradius.cpp
|
||||||
|
|
||||||
composer/qgsattributeselectiondialog.cpp
|
composer/qgsattributeselectiondialog.cpp
|
||||||
composer/qgscomposer.cpp
|
composer/qgscomposer.cpp
|
||||||
@ -217,6 +220,7 @@ SET (QGIS_APP_MOC_HDRS
|
|||||||
|
|
||||||
qgsmaptooladdfeature.h
|
qgsmaptooladdfeature.h
|
||||||
qgsmaptoolcapture.h
|
qgsmaptoolcapture.h
|
||||||
|
qgsmaptoolcircularstringradius.h
|
||||||
qgsmaptooladdpart.h
|
qgsmaptooladdpart.h
|
||||||
qgsmaptooladdring.h
|
qgsmaptooladdring.h
|
||||||
qgsmaptooledit.h
|
qgsmaptooledit.h
|
||||||
@ -245,6 +249,7 @@ SET (QGIS_APP_MOC_HDRS
|
|||||||
qgsmaptoolsimplify.h
|
qgsmaptoolsimplify.h
|
||||||
qgsmaptoolsplitfeatures.h
|
qgsmaptoolsplitfeatures.h
|
||||||
qgsmaptoolsplitparts.h
|
qgsmaptoolsplitparts.h
|
||||||
|
qgsmaptooladdcircularstring.h
|
||||||
|
|
||||||
nodetool/qgsmaptoolnodetool.h
|
nodetool/qgsmaptoolnodetool.h
|
||||||
nodetool/qgsselectedfeature.h
|
nodetool/qgsselectedfeature.h
|
||||||
|
@ -253,6 +253,8 @@
|
|||||||
#include "qgsmaptooladdring.h"
|
#include "qgsmaptooladdring.h"
|
||||||
#include "qgsmaptoolfillring.h"
|
#include "qgsmaptoolfillring.h"
|
||||||
#include "qgsmaptoolannotation.h"
|
#include "qgsmaptoolannotation.h"
|
||||||
|
#include "qgsmaptoolcircularstringcurvepoint.h"
|
||||||
|
#include "qgsmaptoolcircularstringradius.h"
|
||||||
#include "qgsmaptooldeletering.h"
|
#include "qgsmaptooldeletering.h"
|
||||||
#include "qgsmaptooldeletepart.h"
|
#include "qgsmaptooldeletepart.h"
|
||||||
#include "qgsmaptoolfeatureaction.h"
|
#include "qgsmaptoolfeatureaction.h"
|
||||||
@ -288,7 +290,6 @@
|
|||||||
|
|
||||||
// Editor widgets
|
// Editor widgets
|
||||||
#include "qgseditorwidgetregistry.h"
|
#include "qgseditorwidgetregistry.h"
|
||||||
|
|
||||||
//
|
//
|
||||||
// Conditional Includes
|
// Conditional Includes
|
||||||
//
|
//
|
||||||
@ -1206,6 +1207,8 @@ void QgisApp::createActions()
|
|||||||
connect( mActionCopyStyle, SIGNAL( triggered() ), this, SLOT( copyStyle() ) );
|
connect( mActionCopyStyle, SIGNAL( triggered() ), this, SLOT( copyStyle() ) );
|
||||||
connect( mActionPasteStyle, SIGNAL( triggered() ), this, SLOT( pasteStyle() ) );
|
connect( mActionPasteStyle, SIGNAL( triggered() ), this, SLOT( pasteStyle() ) );
|
||||||
connect( mActionAddFeature, SIGNAL( triggered() ), this, SLOT( addFeature() ) );
|
connect( mActionAddFeature, SIGNAL( triggered() ), this, SLOT( addFeature() ) );
|
||||||
|
connect( mActionCircularStringCurvePoint, SIGNAL( triggered() ), this, SLOT( circularStringCurvePoint() ) );
|
||||||
|
connect( mActionCircularStringRadius, SIGNAL( triggered() ), this, SLOT( circularStringRadius() ) );
|
||||||
connect( mActionMoveFeature, SIGNAL( triggered() ), this, SLOT( moveFeature() ) );
|
connect( mActionMoveFeature, SIGNAL( triggered() ), this, SLOT( moveFeature() ) );
|
||||||
connect( mActionRotateFeature, SIGNAL( triggered() ), this, SLOT( rotateFeature() ) );
|
connect( mActionRotateFeature, SIGNAL( triggered() ), this, SLOT( rotateFeature() ) );
|
||||||
|
|
||||||
@ -1480,6 +1483,8 @@ void QgisApp::createActionGroups()
|
|||||||
mMapToolGroup->addAction( mActionMeasureArea );
|
mMapToolGroup->addAction( mActionMeasureArea );
|
||||||
mMapToolGroup->addAction( mActionMeasureAngle );
|
mMapToolGroup->addAction( mActionMeasureAngle );
|
||||||
mMapToolGroup->addAction( mActionAddFeature );
|
mMapToolGroup->addAction( mActionAddFeature );
|
||||||
|
mMapToolGroup->addAction( mActionCircularStringCurvePoint );
|
||||||
|
mMapToolGroup->addAction( mActionCircularStringRadius );
|
||||||
mMapToolGroup->addAction( mActionMoveFeature );
|
mMapToolGroup->addAction( mActionMoveFeature );
|
||||||
mMapToolGroup->addAction( mActionRotateFeature );
|
mMapToolGroup->addAction( mActionRotateFeature );
|
||||||
#if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \
|
#if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \
|
||||||
@ -2329,6 +2334,10 @@ void QgisApp::createCanvasTools()
|
|||||||
mMapTools.mAnnotation->setAction( mActionAnnotation );
|
mMapTools.mAnnotation->setAction( mActionAnnotation );
|
||||||
mMapTools.mAddFeature = new QgsMapToolAddFeature( mMapCanvas );
|
mMapTools.mAddFeature = new QgsMapToolAddFeature( mMapCanvas );
|
||||||
mMapTools.mAddFeature->setAction( mActionAddFeature );
|
mMapTools.mAddFeature->setAction( mActionAddFeature );
|
||||||
|
mMapTools.mCircularStringCurvePoint = new QgsMapToolCircularStringCurvePoint( dynamic_cast<QgsMapToolAddFeature*>( mMapTools.mAddFeature ), mMapCanvas );
|
||||||
|
mMapTools.mCircularStringCurvePoint->setAction( mActionCircularStringCurvePoint );
|
||||||
|
mMapTools.mCircularStringRadius = new QgsMapToolCircularStringRadius( dynamic_cast<QgsMapToolAddFeature*>( mMapTools.mAddFeature ), mMapCanvas );
|
||||||
|
mMapTools.mCircularStringRadius->setAction( mActionCircularStringRadius );
|
||||||
mMapTools.mMoveFeature = new QgsMapToolMoveFeature( mMapCanvas );
|
mMapTools.mMoveFeature = new QgsMapToolMoveFeature( mMapCanvas );
|
||||||
mMapTools.mMoveFeature->setAction( mActionMoveFeature );
|
mMapTools.mMoveFeature->setAction( mActionMoveFeature );
|
||||||
mMapTools.mRotateFeature = new QgsMapToolRotateFeature( mMapCanvas );
|
mMapTools.mRotateFeature = new QgsMapToolRotateFeature( mMapCanvas );
|
||||||
@ -6233,6 +6242,16 @@ void QgisApp::addFeature()
|
|||||||
mMapCanvas->setMapTool( mMapTools.mAddFeature );
|
mMapCanvas->setMapTool( mMapTools.mAddFeature );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QgisApp::circularStringCurvePoint()
|
||||||
|
{
|
||||||
|
mMapCanvas->setMapTool( mMapTools.mCircularStringCurvePoint );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgisApp::circularStringRadius()
|
||||||
|
{
|
||||||
|
mMapCanvas->setMapTool( mMapTools.mCircularStringRadius );
|
||||||
|
}
|
||||||
|
|
||||||
void QgisApp::selectFeatures()
|
void QgisApp::selectFeatures()
|
||||||
{
|
{
|
||||||
mMapCanvas->setMapTool( mMapTools.mSelectFeatures );
|
mMapCanvas->setMapTool( mMapTools.mSelectFeatures );
|
||||||
|
@ -971,6 +971,10 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
|
|||||||
void newBookmark();
|
void newBookmark();
|
||||||
//! activates the add feature tool
|
//! activates the add feature tool
|
||||||
void addFeature();
|
void addFeature();
|
||||||
|
//! activates the add circular string tool
|
||||||
|
void circularStringCurvePoint();
|
||||||
|
//! activates the circular string radius tool
|
||||||
|
void circularStringRadius();
|
||||||
//! activates the move feature tool
|
//! activates the move feature tool
|
||||||
void moveFeature();
|
void moveFeature();
|
||||||
//! activates the offset curve tool
|
//! activates the offset curve tool
|
||||||
@ -1481,6 +1485,8 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
|
|||||||
QgsMapTool *mMeasureArea;
|
QgsMapTool *mMeasureArea;
|
||||||
QgsMapTool *mMeasureAngle;
|
QgsMapTool *mMeasureAngle;
|
||||||
QgsMapTool *mAddFeature;
|
QgsMapTool *mAddFeature;
|
||||||
|
QgsMapTool *mCircularStringCurvePoint;
|
||||||
|
QgsMapTool *mCircularStringRadius;
|
||||||
QgsMapTool *mMoveFeature;
|
QgsMapTool *mMoveFeature;
|
||||||
QgsMapTool *mOffsetCurve;
|
QgsMapTool *mOffsetCurve;
|
||||||
QgsMapTool *mReshapeFeatures;
|
QgsMapTool *mReshapeFeatures;
|
||||||
|
182
src/app/qgsmaptooladdcircularstring.cpp
Normal file
182
src/app/qgsmaptooladdcircularstring.cpp
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
qgsmaptooladdcircularstring.h - map tool for adding circular strings
|
||||||
|
---------------------
|
||||||
|
begin : December 2014
|
||||||
|
copyright : (C) 2014 by Marco Hugentobler
|
||||||
|
email : marco dot hugentobler at sourcepole dot ch
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include "qgsmaptooladdcircularstring.h"
|
||||||
|
#include "qgscircularstringv2.h"
|
||||||
|
#include "qgscompoundcurvev2.h"
|
||||||
|
#include "qgscurvepolygonv2.h"
|
||||||
|
#include "qgsgeometryrubberband.h"
|
||||||
|
#include "qgsgeometryutils.h"
|
||||||
|
#include "qgslinestringv2.h"
|
||||||
|
#include "qgsmapcanvas.h"
|
||||||
|
#include "qgspointv2.h"
|
||||||
|
#include <QMouseEvent>
|
||||||
|
|
||||||
|
QgsMapToolAddCircularString::QgsMapToolAddCircularString( QgsMapToolCapture* parentTool, QgsMapCanvas* canvas, CaptureMode mode ): QgsMapToolCapture( canvas, mode ),
|
||||||
|
mParentTool( parentTool ), mRubberBand( 0 ), mShowCenterPointRubberBand( false ), mCenterPointRubberBand( 0 )
|
||||||
|
{
|
||||||
|
if ( mCanvas )
|
||||||
|
{
|
||||||
|
connect( mCanvas, SIGNAL( mapToolSet( QgsMapTool*, QgsMapTool* ) ), this, SLOT( setParentTool( QgsMapTool*, QgsMapTool* ) ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsMapToolAddCircularString::QgsMapToolAddCircularString( QgsMapCanvas* canvas ): QgsMapToolCapture( canvas ), mParentTool( 0 ),
|
||||||
|
mRubberBand( 0 ), mShowCenterPointRubberBand( false ), mCenterPointRubberBand( 0 )
|
||||||
|
{
|
||||||
|
if ( mCanvas )
|
||||||
|
{
|
||||||
|
connect( mCanvas, SIGNAL( mapToolSet( QgsMapTool*, QgsMapTool* ) ), this, SLOT( setParentTool( QgsMapTool*, QgsMapTool* ) ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsMapToolAddCircularString::~QgsMapToolAddCircularString()
|
||||||
|
{
|
||||||
|
delete mRubberBand;
|
||||||
|
removeCenterPointRubberBand();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsMapToolAddCircularString::setParentTool( QgsMapTool* newTool, QgsMapTool* oldTool )
|
||||||
|
{
|
||||||
|
QgsMapToolCapture* tool = dynamic_cast<QgsMapToolCapture*>( oldTool );
|
||||||
|
QgsMapToolAddCircularString* csTool = dynamic_cast<QgsMapToolAddCircularString*>( oldTool );
|
||||||
|
if ( csTool && newTool == this )
|
||||||
|
{
|
||||||
|
mParentTool = csTool->mParentTool;
|
||||||
|
}
|
||||||
|
else if ( tool && newTool == this )
|
||||||
|
{
|
||||||
|
mParentTool = tool;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsMapToolAddCircularString::keyPressEvent( QKeyEvent* e )
|
||||||
|
{
|
||||||
|
if ( e->isAutoRepeat() )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( e && e->key() == Qt::Key_R )
|
||||||
|
{
|
||||||
|
mShowCenterPointRubberBand = true;
|
||||||
|
|
||||||
|
createCenterPointRubberBand();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsMapToolAddCircularString::keyReleaseEvent( QKeyEvent* e )
|
||||||
|
{
|
||||||
|
if ( e->isAutoRepeat() )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( e && e->key() == Qt::Key_R )
|
||||||
|
{
|
||||||
|
removeCenterPointRubberBand();
|
||||||
|
mShowCenterPointRubberBand = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsMapToolAddCircularString::deactivate()
|
||||||
|
{
|
||||||
|
if ( !mParentTool || mPoints.size() < 3 )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( mPoints.size() % 2 == 0 ) //a valid circularstring needs to have an odd number of vertices
|
||||||
|
{
|
||||||
|
mPoints.removeLast();
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsCircularStringV2* c = new QgsCircularStringV2();
|
||||||
|
c->setPoints( mPoints );
|
||||||
|
mParentTool->addCurve( c );
|
||||||
|
mPoints.clear();
|
||||||
|
delete mRubberBand; mRubberBand = 0;
|
||||||
|
removeCenterPointRubberBand();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsMapToolAddCircularString::createCenterPointRubberBand()
|
||||||
|
{
|
||||||
|
if ( !mShowCenterPointRubberBand || mPoints.size() < 2 || mPoints.size() % 2 != 0 )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mCenterPointRubberBand = createGeometryRubberBand( QGis::Polygon );
|
||||||
|
mCenterPointRubberBand->show();
|
||||||
|
|
||||||
|
if ( mRubberBand )
|
||||||
|
{
|
||||||
|
const QgsAbstractGeometryV2* rubberBandGeom = mRubberBand->geometry();
|
||||||
|
if ( rubberBandGeom )
|
||||||
|
{
|
||||||
|
QgsVertexId idx; idx.part = 0; idx.ring = 0; idx.vertex = mPoints.size();
|
||||||
|
QgsPointV2 pt = rubberBandGeom->vertexAt( idx );
|
||||||
|
updateCenterPointRubberBand( pt );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsMapToolAddCircularString::updateCenterPointRubberBand( const QgsPointV2& pt )
|
||||||
|
{
|
||||||
|
if ( !mShowCenterPointRubberBand || !mCenterPointRubberBand || mPoints.size() < 2 )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (( mPoints.size() ) % 2 != 0 )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//create circular string
|
||||||
|
QgsCircularStringV2* cs = new QgsCircularStringV2();
|
||||||
|
QList< QgsPointV2 > csPoints;
|
||||||
|
csPoints.append( mPoints.at( mPoints.size() - 2 ) );
|
||||||
|
csPoints.append( mPoints.at( mPoints.size() - 1 ) );
|
||||||
|
csPoints.append( pt );
|
||||||
|
cs->setPoints( csPoints );
|
||||||
|
|
||||||
|
double centerX, centerY;
|
||||||
|
double radius;
|
||||||
|
QgsGeometryUtils::circleCenterRadius( csPoints.at( 0 ), csPoints.at( 1 ), csPoints.at( 2 ), radius, centerX, centerY );
|
||||||
|
|
||||||
|
QgsLineStringV2* segment1 = new QgsLineStringV2();
|
||||||
|
segment1->addVertex( QgsPointV2( centerX, centerY ) );
|
||||||
|
segment1->addVertex( csPoints.at( 0 ) );
|
||||||
|
|
||||||
|
QgsLineStringV2* segment2 = new QgsLineStringV2();
|
||||||
|
segment2->addVertex( csPoints.at( 2 ) );
|
||||||
|
segment2->addVertex( QgsPointV2( centerX, centerY ) );
|
||||||
|
|
||||||
|
QgsCompoundCurveV2* cc = new QgsCompoundCurveV2();
|
||||||
|
cc->addCurve( segment1 );
|
||||||
|
cc->addCurve( cs );
|
||||||
|
cc->addCurve( segment2 );
|
||||||
|
|
||||||
|
QgsCurvePolygonV2* cp = new QgsCurvePolygonV2();
|
||||||
|
cp->setExteriorRing( cc );
|
||||||
|
mCenterPointRubberBand->setGeometry( cp );
|
||||||
|
mCenterPointRubberBand->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsMapToolAddCircularString::removeCenterPointRubberBand()
|
||||||
|
{
|
||||||
|
delete mCenterPointRubberBand; mCenterPointRubberBand = 0;
|
||||||
|
}
|
55
src/app/qgsmaptooladdcircularstring.h
Normal file
55
src/app/qgsmaptooladdcircularstring.h
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
qgsmaptooladdcircularstring.h - map tool for adding circular strings
|
||||||
|
---------------------
|
||||||
|
begin : December 2014
|
||||||
|
copyright : (C) 2014 by Marco Hugentobler
|
||||||
|
email : marco dot hugentobler at sourcepole dot ch
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QGSMAPTOOLADDCIRCULARSTRING_H
|
||||||
|
#define QGSMAPTOOLADDCIRCULARSTRING_H
|
||||||
|
|
||||||
|
#include "qgsmaptoolcapture.h"
|
||||||
|
|
||||||
|
class QgsGeometryRubberBand;
|
||||||
|
|
||||||
|
class QgsMapToolAddCircularString: public QgsMapToolCapture
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
QgsMapToolAddCircularString( QgsMapToolCapture* parentTool, QgsMapCanvas* canvas, CaptureMode mode = CaptureLine );
|
||||||
|
~QgsMapToolAddCircularString();
|
||||||
|
|
||||||
|
void keyPressEvent( QKeyEvent* e );
|
||||||
|
void keyReleaseEvent( QKeyEvent* e );
|
||||||
|
|
||||||
|
void deactivate();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void setParentTool( QgsMapTool* newTool, QgsMapTool* oldTool );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QgsMapToolAddCircularString( QgsMapCanvas* canvas = 0 ); //forbidden
|
||||||
|
|
||||||
|
QgsMapToolCapture* mParentTool;
|
||||||
|
/** Circular string points (in map coordinates)*/
|
||||||
|
QList< QgsPointV2 > mPoints;
|
||||||
|
QgsGeometryRubberBand* mRubberBand;
|
||||||
|
|
||||||
|
//center point rubber band
|
||||||
|
bool mShowCenterPointRubberBand;
|
||||||
|
QgsGeometryRubberBand* mCenterPointRubberBand;
|
||||||
|
|
||||||
|
void createCenterPointRubberBand();
|
||||||
|
void updateCenterPointRubberBand( const QgsPointV2& pt );
|
||||||
|
void removeCenterPointRubberBand();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QGSMAPTOOLADDCIRCULARSTRING_H
|
@ -17,11 +17,14 @@
|
|||||||
#include "qgsapplication.h"
|
#include "qgsapplication.h"
|
||||||
#include "qgsattributedialog.h"
|
#include "qgsattributedialog.h"
|
||||||
#include "qgscsexception.h"
|
#include "qgscsexception.h"
|
||||||
|
#include "qgscurvepolygonv2.h"
|
||||||
#include "qgsfield.h"
|
#include "qgsfield.h"
|
||||||
#include "qgsgeometry.h"
|
#include "qgsgeometry.h"
|
||||||
|
#include "qgslinestringv2.h"
|
||||||
#include "qgsmapcanvas.h"
|
#include "qgsmapcanvas.h"
|
||||||
#include "qgsmaplayerregistry.h"
|
#include "qgsmaplayerregistry.h"
|
||||||
#include "qgsmapmouseevent.h"
|
#include "qgsmapmouseevent.h"
|
||||||
|
#include "qgspolygonv2.h"
|
||||||
#include "qgsproject.h"
|
#include "qgsproject.h"
|
||||||
#include "qgsvectordataprovider.h"
|
#include "qgsvectordataprovider.h"
|
||||||
#include "qgsvectorlayer.h"
|
#include "qgsvectorlayer.h"
|
||||||
@ -199,56 +202,46 @@ void QgsMapToolAddFeature::canvasMapReleaseEvent( QgsMapMouseEvent* e )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( mode() == CapturePolygon )
|
||||||
|
{
|
||||||
|
closePolygon();
|
||||||
|
}
|
||||||
|
|
||||||
//create QgsFeature with wkb representation
|
//create QgsFeature with wkb representation
|
||||||
QgsFeature* f = new QgsFeature( vlayer->fields(), 0 );
|
QgsFeature* f = new QgsFeature( vlayer->fields(), 0 );
|
||||||
|
|
||||||
QgsGeometry *g;
|
//does compoundcurve contain circular strings?
|
||||||
|
//does provider support circular strings?
|
||||||
|
bool hasCurvedSegments = captureCurve()->hasCurvedSegments();
|
||||||
|
bool providerSupportsCurvedSegments = vlayer->dataProvider()->capabilities() & QgsVectorDataProvider::CircularGeometries;
|
||||||
|
|
||||||
|
QgsCurveV2* curveToAdd = 0;
|
||||||
|
if ( hasCurvedSegments && providerSupportsCurvedSegments )
|
||||||
|
{
|
||||||
|
curveToAdd = dynamic_cast<QgsCurveV2*>( captureCurve()->clone() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
curveToAdd = captureCurve()->curveToLine();
|
||||||
|
}
|
||||||
|
|
||||||
if ( mode() == CaptureLine )
|
if ( mode() == CaptureLine )
|
||||||
{
|
{
|
||||||
if ( layerWKBType == QGis::WKBLineString || layerWKBType == QGis::WKBLineString25D )
|
f->setGeometry( new QgsGeometry( curveToAdd ) );
|
||||||
{
|
|
||||||
g = QgsGeometry::fromPolyline( points().toVector() );
|
|
||||||
}
|
|
||||||
else if ( layerWKBType == QGis::WKBMultiLineString || layerWKBType == QGis::WKBMultiLineString25D )
|
|
||||||
{
|
|
||||||
g = QgsGeometry::fromMultiPolyline( QgsMultiPolyline() << points().toVector() );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
emit messageEmitted( tr( "Cannot add feature. Unknown WKB type" ), QgsMessageBar::CRITICAL );
|
|
||||||
stopCapturing();
|
|
||||||
delete f;
|
|
||||||
return; //unknown wkbtype
|
|
||||||
}
|
|
||||||
|
|
||||||
f->setGeometry( g );
|
|
||||||
}
|
}
|
||||||
else // polygon
|
else
|
||||||
{
|
{
|
||||||
if ( layerWKBType == QGis::WKBPolygon || layerWKBType == QGis::WKBPolygon25D )
|
QgsCurvePolygonV2* poly = 0;
|
||||||
|
if ( hasCurvedSegments && providerSupportsCurvedSegments )
|
||||||
{
|
{
|
||||||
g = QgsGeometry::fromPolygon( QgsPolygon() << points().toVector() );
|
poly = new QgsCurvePolygonV2();
|
||||||
}
|
|
||||||
else if ( layerWKBType == QGis::WKBMultiPolygon || layerWKBType == QGis::WKBMultiPolygon25D )
|
|
||||||
{
|
|
||||||
g = QgsGeometry::fromMultiPolygon( QgsMultiPolygon() << ( QgsPolygon() << points().toVector() ) );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
emit messageEmitted( tr( "Cannot add feature. Unknown WKB type" ), QgsMessageBar::CRITICAL );
|
poly = new QgsPolygonV2();
|
||||||
stopCapturing();
|
|
||||||
delete f;
|
|
||||||
return; //unknown wkbtype
|
|
||||||
}
|
}
|
||||||
|
poly->setExteriorRing( curveToAdd );
|
||||||
if ( !g )
|
f->setGeometry( poly );
|
||||||
{
|
|
||||||
stopCapturing();
|
|
||||||
delete f;
|
|
||||||
return; // invalid geometry; one possibility is from duplicate points
|
|
||||||
}
|
|
||||||
f->setGeometry( g );
|
|
||||||
|
|
||||||
int avoidIntersectionsReturn = f->geometry()->avoidIntersections();
|
int avoidIntersectionsReturn = f->geometry()->avoidIntersections();
|
||||||
if ( avoidIntersectionsReturn == 1 )
|
if ( avoidIntersectionsReturn == 1 )
|
||||||
|
@ -14,9 +14,12 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include "qgsmaptooladdpart.h"
|
#include "qgsmaptooladdpart.h"
|
||||||
|
#include "qgscurvepolygonv2.h"
|
||||||
#include "qgsgeometry.h"
|
#include "qgsgeometry.h"
|
||||||
|
#include "qgslinestringv2.h"
|
||||||
#include "qgsmapcanvas.h"
|
#include "qgsmapcanvas.h"
|
||||||
#include "qgsproject.h"
|
#include "qgsproject.h"
|
||||||
|
#include "qgsvectordataprovider.h"
|
||||||
#include "qgsvectorlayer.h"
|
#include "qgsvectorlayer.h"
|
||||||
#include "qgslogger.h"
|
#include "qgslogger.h"
|
||||||
|
|
||||||
@ -67,7 +70,7 @@ void QgsMapToolAddPart::canvasMapReleaseEvent( QgsMapMouseEvent * e )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int errorCode;
|
int errorCode = 0;
|
||||||
switch ( mode() )
|
switch ( mode() )
|
||||||
{
|
{
|
||||||
case CapturePoint:
|
case CapturePoint:
|
||||||
@ -118,33 +121,51 @@ void QgsMapToolAddPart::canvasMapReleaseEvent( QgsMapMouseEvent * e )
|
|||||||
if ( !isCapturing() )
|
if ( !isCapturing() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// we are now going to finish the capturing
|
|
||||||
|
|
||||||
if ( mode() == CapturePolygon )
|
if ( mode() == CapturePolygon )
|
||||||
{
|
{
|
||||||
//close polygon
|
|
||||||
closePolygon();
|
closePolygon();
|
||||||
//avoid intersections
|
}
|
||||||
QgsGeometry* geom = QgsGeometry::fromPolygon( QgsPolygon() << points().toVector() );
|
|
||||||
if ( geom )
|
//does compoundcurve contain circular strings?
|
||||||
{
|
//does provider support circular strings?
|
||||||
geom->avoidIntersections();
|
bool hasCurvedSegments = captureCurve()->hasCurvedSegments();
|
||||||
QgsPolygon poly = geom->asPolygon();
|
bool providerSupportsCurvedSegments = vlayer->dataProvider()->capabilities() & QgsVectorDataProvider::CircularGeometries;
|
||||||
if ( poly.size() < 1 )
|
|
||||||
{
|
QgsCurveV2* curveToAdd = 0;
|
||||||
stopCapturing();
|
if ( hasCurvedSegments && providerSupportsCurvedSegments )
|
||||||
delete geom;
|
{
|
||||||
vlayer->destroyEditCommand();
|
curveToAdd = dynamic_cast<QgsCurveV2*>( captureCurve()->clone() );
|
||||||
return;
|
}
|
||||||
}
|
else
|
||||||
setPoints( geom->asPolygon()[0].toList() );
|
{
|
||||||
delete geom;
|
curveToAdd = captureCurve()->curveToLine();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vlayer->beginEditCommand( tr( "Part added" ) );
|
vlayer->beginEditCommand( tr( "Part added" ) );
|
||||||
errorCode = vlayer->addPart( points() );
|
if ( mode() == CapturePolygon )
|
||||||
|
{
|
||||||
|
//avoid intersections
|
||||||
|
QgsCurvePolygonV2* cp = new QgsCurvePolygonV2();
|
||||||
|
cp->setExteriorRing( curveToAdd );
|
||||||
|
QgsGeometry* geom = new QgsGeometry( cp );
|
||||||
|
geom->avoidIntersections();
|
||||||
|
|
||||||
|
const QgsCurvePolygonV2* cpGeom = dynamic_cast<const QgsCurvePolygonV2*>( geom->geometry() );
|
||||||
|
if ( !cpGeom )
|
||||||
|
{
|
||||||
|
stopCapturing();
|
||||||
|
delete geom;
|
||||||
|
vlayer->destroyEditCommand();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
errorCode = vlayer->addPart( dynamic_cast<QgsCurveV2*>( cpGeom->exteriorRing()->clone() ) );
|
||||||
|
delete geom;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
errorCode = vlayer->addPart( curveToAdd );
|
||||||
|
}
|
||||||
stopCapturing();
|
stopCapturing();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -17,8 +17,10 @@
|
|||||||
|
|
||||||
#include "qgsmaptooladdring.h"
|
#include "qgsmaptooladdring.h"
|
||||||
#include "qgsgeometry.h"
|
#include "qgsgeometry.h"
|
||||||
|
#include "qgslinestringv2.h"
|
||||||
#include "qgsmapcanvas.h"
|
#include "qgsmapcanvas.h"
|
||||||
#include "qgsproject.h"
|
#include "qgsproject.h"
|
||||||
|
#include "qgsvectordataprovider.h"
|
||||||
#include "qgsvectorlayer.h"
|
#include "qgsvectorlayer.h"
|
||||||
|
|
||||||
|
|
||||||
@ -80,7 +82,23 @@ void QgsMapToolAddRing::canvasMapReleaseEvent( QgsMapMouseEvent * e )
|
|||||||
closePolygon();
|
closePolygon();
|
||||||
|
|
||||||
vlayer->beginEditCommand( tr( "Ring added" ) );
|
vlayer->beginEditCommand( tr( "Ring added" ) );
|
||||||
int addRingReturnCode = vlayer->addRing( points() );
|
|
||||||
|
//does compoundcurve contain circular strings?
|
||||||
|
//does provider support circular strings?
|
||||||
|
bool hasCurvedSegments = captureCurve()->hasCurvedSegments();
|
||||||
|
bool providerSupportsCurvedSegments = vlayer->dataProvider()->capabilities() & QgsVectorDataProvider::CircularGeometries;
|
||||||
|
|
||||||
|
QgsCurveV2* curveToAdd = 0;
|
||||||
|
if ( hasCurvedSegments && providerSupportsCurvedSegments )
|
||||||
|
{
|
||||||
|
curveToAdd = dynamic_cast<QgsCurveV2*>( captureCurve()->clone() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
curveToAdd = captureCurve()->curveToLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
int addRingReturnCode = vlayer->addRing( curveToAdd );
|
||||||
if ( addRingReturnCode != 0 )
|
if ( addRingReturnCode != 0 )
|
||||||
{
|
{
|
||||||
QString errorMessage;
|
QString errorMessage;
|
||||||
|
@ -19,10 +19,12 @@
|
|||||||
#include "qgscursors.h"
|
#include "qgscursors.h"
|
||||||
#include "qgsgeometryvalidator.h"
|
#include "qgsgeometryvalidator.h"
|
||||||
#include "qgslayertreeview.h"
|
#include "qgslayertreeview.h"
|
||||||
|
#include "qgslinestringv2.h"
|
||||||
#include "qgslogger.h"
|
#include "qgslogger.h"
|
||||||
#include "qgsmapcanvas.h"
|
#include "qgsmapcanvas.h"
|
||||||
#include "qgsmapmouseevent.h"
|
#include "qgsmapmouseevent.h"
|
||||||
#include "qgsmaprenderer.h"
|
#include "qgsmaprenderer.h"
|
||||||
|
#include "qgspolygonv2.h"
|
||||||
#include "qgsrubberband.h"
|
#include "qgsrubberband.h"
|
||||||
#include "qgsvectorlayer.h"
|
#include "qgsvectorlayer.h"
|
||||||
#include "qgsvertexmarker.h"
|
#include "qgsvertexmarker.h"
|
||||||
@ -167,6 +169,13 @@ int QgsMapToolCapture::nextPoint( const QgsPoint& mapPoint, QgsPoint& layerPoint
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int QgsMapToolCapture::nextPoint( const QPoint &p, QgsPoint &layerPoint, QgsPoint &mapPoint )
|
||||||
|
{
|
||||||
|
|
||||||
|
mapPoint = toMapCoordinates( p );
|
||||||
|
return nextPoint( mapPoint, layerPoint );
|
||||||
|
}
|
||||||
|
|
||||||
int QgsMapToolCapture::addVertex( const QgsPoint& point )
|
int QgsMapToolCapture::addVertex( const QgsPoint& point )
|
||||||
{
|
{
|
||||||
if ( mode() == CaptureNone )
|
if ( mode() == CaptureNone )
|
||||||
@ -188,7 +197,7 @@ int QgsMapToolCapture::addVertex( const QgsPoint& point )
|
|||||||
mRubberBand = createRubberBand( mCaptureMode == CapturePolygon ? QGis::Polygon : QGis::Line );
|
mRubberBand = createRubberBand( mCaptureMode == CapturePolygon ? QGis::Polygon : QGis::Line );
|
||||||
}
|
}
|
||||||
mRubberBand->addPoint( point );
|
mRubberBand->addPoint( point );
|
||||||
mCaptureList.append( layerPoint );
|
mCaptureCurve.addVertex( QgsPointV2( layerPoint.x(), layerPoint.y() ) );
|
||||||
|
|
||||||
if ( !mTempRubberBand )
|
if ( !mTempRubberBand )
|
||||||
{
|
{
|
||||||
@ -215,6 +224,51 @@ int QgsMapToolCapture::addVertex( const QgsPoint& point )
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int QgsMapToolCapture::addCurve( QgsCurveV2* c )
|
||||||
|
{
|
||||||
|
if ( !c )
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !mRubberBand )
|
||||||
|
{
|
||||||
|
mRubberBand = createRubberBand( mCaptureMode == CapturePolygon ? QGis::Polygon : QGis::Line );
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsLineStringV2* lineString = c->curveToLine();
|
||||||
|
QList<QgsPointV2> linePoints;
|
||||||
|
lineString->points( linePoints );
|
||||||
|
delete lineString;
|
||||||
|
QList<QgsPointV2>::const_iterator ptIt = linePoints.constBegin();
|
||||||
|
for ( ; ptIt != linePoints.constEnd(); ++ptIt )
|
||||||
|
{
|
||||||
|
mRubberBand->addPoint( QgsPoint( ptIt->x(), ptIt->y() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !mTempRubberBand )
|
||||||
|
{
|
||||||
|
mTempRubberBand = createRubberBand( mCaptureMode == CapturePolygon ? QGis::Polygon : QGis::Line, true );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mTempRubberBand->reset();
|
||||||
|
}
|
||||||
|
QgsPointV2 endPt = c->endPoint();
|
||||||
|
mTempRubberBand->addPoint( QgsPoint( endPt.x(), endPt.y() ) ); //add last point of c
|
||||||
|
|
||||||
|
//transform back to layer CRS in case map CRS and layer CRS are different
|
||||||
|
QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
|
||||||
|
const QgsCoordinateTransform* ct = mCanvas->mapSettings().layerTransform( vlayer );
|
||||||
|
if ( ct )
|
||||||
|
{
|
||||||
|
c->transform( *ct, QgsCoordinateTransform::ReverseTransform );
|
||||||
|
}
|
||||||
|
mCaptureCurve.addCurve( c );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void QgsMapToolCapture::undo()
|
void QgsMapToolCapture::undo()
|
||||||
{
|
{
|
||||||
@ -222,7 +276,7 @@ void QgsMapToolCapture::undo()
|
|||||||
{
|
{
|
||||||
int rubberBandSize = mRubberBand->numberOfVertices();
|
int rubberBandSize = mRubberBand->numberOfVertices();
|
||||||
int tempRubberBandSize = mTempRubberBand->numberOfVertices();
|
int tempRubberBandSize = mTempRubberBand->numberOfVertices();
|
||||||
int captureListSize = mCaptureList.size();
|
int captureListSize = size();
|
||||||
|
|
||||||
if ( rubberBandSize < 1 || captureListSize < 1 )
|
if ( rubberBandSize < 1 || captureListSize < 1 )
|
||||||
{
|
{
|
||||||
@ -244,7 +298,9 @@ void QgsMapToolCapture::undo()
|
|||||||
mTempRubberBand->reset( mCaptureMode == CapturePolygon ? true : false );
|
mTempRubberBand->reset( mCaptureMode == CapturePolygon ? true : false );
|
||||||
}
|
}
|
||||||
|
|
||||||
mCaptureList.removeLast();
|
QgsVertexId vertexToRemove;
|
||||||
|
vertexToRemove.part = 0; vertexToRemove.ring = 0; vertexToRemove.vertex = size() - 1;
|
||||||
|
mCaptureCurve.deleteVertex( vertexToRemove );
|
||||||
|
|
||||||
validateGeometry();
|
validateGeometry();
|
||||||
}
|
}
|
||||||
@ -298,7 +354,7 @@ void QgsMapToolCapture::stopCapturing()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
mCapturing = false;
|
mCapturing = false;
|
||||||
mCaptureList.clear();
|
mCaptureCurve.clear();
|
||||||
mCanvas->refresh();
|
mCanvas->refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,7 +369,7 @@ void QgsMapToolCapture::deleteTempRubberBand()
|
|||||||
|
|
||||||
void QgsMapToolCapture::closePolygon()
|
void QgsMapToolCapture::closePolygon()
|
||||||
{
|
{
|
||||||
mCaptureList.append( mCaptureList[0] );
|
mCaptureCurve.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsMapToolCapture::validateGeometry()
|
void QgsMapToolCapture::validateGeometry()
|
||||||
@ -343,14 +399,18 @@ void QgsMapToolCapture::validateGeometry()
|
|||||||
case CapturePoint:
|
case CapturePoint:
|
||||||
return;
|
return;
|
||||||
case CaptureLine:
|
case CaptureLine:
|
||||||
if ( mCaptureList.size() < 2 )
|
if ( size() < 2 )
|
||||||
return;
|
return;
|
||||||
g = QgsGeometry::fromPolyline( mCaptureList.toVector() );
|
g = new QgsGeometry( mCaptureCurve.curveToLine() );
|
||||||
break;
|
break;
|
||||||
case CapturePolygon:
|
case CapturePolygon:
|
||||||
if ( mCaptureList.size() < 3 )
|
if ( size() < 3 )
|
||||||
return;
|
return;
|
||||||
g = QgsGeometry::fromPolygon( QgsPolygon() << ( QgsPolyline() << mCaptureList.toVector() << mCaptureList[0] ) );
|
QgsLineStringV2* exteriorRing = mCaptureCurve.curveToLine();
|
||||||
|
exteriorRing->close();
|
||||||
|
QgsPolygonV2* polygon = new QgsPolygonV2();
|
||||||
|
polygon->setExteriorRing( exteriorRing );
|
||||||
|
g = new QgsGeometry( polygon );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,3 +462,29 @@ void QgsMapToolCapture::validationFinished()
|
|||||||
QStatusBar *sb = QgisApp::instance()->statusBar();
|
QStatusBar *sb = QgisApp::instance()->statusBar();
|
||||||
sb->showMessage( tr( "Validation finished." ) );
|
sb->showMessage( tr( "Validation finished." ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int QgsMapToolCapture::size()
|
||||||
|
{
|
||||||
|
return mCaptureCurve.numPoints();
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QgsPoint> QgsMapToolCapture::points()
|
||||||
|
{
|
||||||
|
QList<QgsPointV2> pts;
|
||||||
|
QList<QgsPoint> points;
|
||||||
|
mCaptureCurve.points( pts );
|
||||||
|
QgsGeometry::convertPointList( pts, points );
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsMapToolCapture::setPoints( const QList<QgsPoint>& pointList )
|
||||||
|
{
|
||||||
|
QList<QgsPointV2> pts;
|
||||||
|
QgsGeometry::convertPointList( pointList, pts );
|
||||||
|
|
||||||
|
QgsLineStringV2* line = new QgsLineStringV2();
|
||||||
|
line->setPoints( pts );
|
||||||
|
|
||||||
|
mCaptureCurve.clear();
|
||||||
|
mCaptureCurve.addCurve( line );
|
||||||
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "qgsmaptooledit.h"
|
#include "qgsmaptooledit.h"
|
||||||
|
#include "qgscompoundcurvev2.h"
|
||||||
#include "qgspoint.h"
|
#include "qgspoint.h"
|
||||||
#include "qgsgeometry.h"
|
#include "qgsgeometry.h"
|
||||||
|
|
||||||
@ -52,6 +53,11 @@ class APP_EXPORT QgsMapToolCapture : public QgsMapToolEdit
|
|||||||
//! deactive the tool
|
//! deactive the tool
|
||||||
virtual void deactivate() override;
|
virtual void deactivate() override;
|
||||||
|
|
||||||
|
/** Adds a whole curve (e.g. circularstring) to the captured geometry. Curve must be in map CRS*/
|
||||||
|
int addCurve( QgsCurveV2* c );
|
||||||
|
|
||||||
|
const QgsCompoundCurveV2* captureCurve() const { return &mCaptureCurve; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void currentLayerChanged( QgsMapLayer *layer );
|
void currentLayerChanged( QgsMapLayer *layer );
|
||||||
void addError( QgsGeometry::Error );
|
void addError( QgsGeometry::Error );
|
||||||
@ -59,6 +65,7 @@ class APP_EXPORT QgsMapToolCapture : public QgsMapToolEdit
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
int nextPoint( const QgsPoint& mapPoint, QgsPoint& layerPoint );
|
int nextPoint( const QgsPoint& mapPoint, QgsPoint& layerPoint );
|
||||||
|
int nextPoint( const QPoint &p, QgsPoint &layerPoint, QgsPoint &mapPoint );
|
||||||
|
|
||||||
/** Adds a point to the rubber band (in map coordinates) and to the capture list (in layer coordinates)
|
/** 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*/
|
@return 0 in case of success, 1 if current layer is not a vector layer, 2 if coordinate transformation failed*/
|
||||||
@ -72,11 +79,9 @@ class APP_EXPORT QgsMapToolCapture : public QgsMapToolEdit
|
|||||||
void stopCapturing();
|
void stopCapturing();
|
||||||
void deleteTempRubberBand();
|
void deleteTempRubberBand();
|
||||||
|
|
||||||
int size() { return mCaptureList.size(); }
|
int size();
|
||||||
QList<QgsPoint>::iterator begin() { return mCaptureList.begin(); }
|
QList<QgsPoint> points();
|
||||||
QList<QgsPoint>::iterator end() { return mCaptureList.end(); }
|
void setPoints( const QList<QgsPoint>& pointList );
|
||||||
const QList<QgsPoint> &points() { return mCaptureList; }
|
|
||||||
void setPoints( const QList<QgsPoint>& pointList ) { mCaptureList = pointList; }
|
|
||||||
void closePolygon();
|
void closePolygon();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -90,7 +95,7 @@ class APP_EXPORT QgsMapToolCapture : public QgsMapToolEdit
|
|||||||
QgsRubberBand* mTempRubberBand;
|
QgsRubberBand* mTempRubberBand;
|
||||||
|
|
||||||
/** List to store the points of digitised lines and polygons (in layer coordinates)*/
|
/** List to store the points of digitised lines and polygons (in layer coordinates)*/
|
||||||
QList<QgsPoint> mCaptureList;
|
QgsCompoundCurveV2 mCaptureCurve;
|
||||||
|
|
||||||
void validateGeometry();
|
void validateGeometry();
|
||||||
QString mTip;
|
QString mTip;
|
||||||
|
87
src/app/qgsmaptoolcircularstringcurvepoint.cpp
Normal file
87
src/app/qgsmaptoolcircularstringcurvepoint.cpp
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#include "qgsmaptoolcircularstringcurvepoint.h"
|
||||||
|
#include "qgscircularstringv2.h"
|
||||||
|
#include "qgscompoundcurvev2.h"
|
||||||
|
#include "qgsgeometryrubberband.h"
|
||||||
|
#include "qgsmapcanvas.h"
|
||||||
|
#include "qgspointv2.h"
|
||||||
|
#include <QMouseEvent>
|
||||||
|
|
||||||
|
QgsMapToolCircularStringCurvePoint::QgsMapToolCircularStringCurvePoint( QgsMapToolCapture* parentTool,
|
||||||
|
QgsMapCanvas* canvas, CaptureMode mode ): QgsMapToolAddCircularString( parentTool, canvas, mode )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsMapToolCircularStringCurvePoint::~QgsMapToolCircularStringCurvePoint()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsMapToolCircularStringCurvePoint::canvasMapReleaseEvent( QgsMapMouseEvent* e )
|
||||||
|
{
|
||||||
|
QgsPointV2 mapPoint( e->mapPoint().x(), e->mapPoint().y() );
|
||||||
|
|
||||||
|
if ( e->button() == Qt::LeftButton )
|
||||||
|
{
|
||||||
|
if ( mPoints.size() < 1 ) //connection to vertex of previous line segment needed?
|
||||||
|
{
|
||||||
|
const QgsCompoundCurveV2* compoundCurve = mParentTool->captureCurve();
|
||||||
|
if ( compoundCurve )
|
||||||
|
{
|
||||||
|
if ( compoundCurve->nCurves() > 0 )
|
||||||
|
{
|
||||||
|
const QgsCurveV2* curve = compoundCurve->curveAt( compoundCurve->nCurves() - 1 );
|
||||||
|
if ( curve )
|
||||||
|
{
|
||||||
|
//mParentTool->captureCurve() is in layer coordinates, but we need map coordinates
|
||||||
|
QgsPointV2 endPointLayerCoord = curve->endPoint();
|
||||||
|
QgsPoint mapPoint = toMapCoordinates( mCanvas->currentLayer(), QgsPoint( endPointLayerCoord.x(), endPointLayerCoord.y() ) );
|
||||||
|
mPoints.append( QgsPointV2( mapPoint.x(), mapPoint.y() ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mPoints.append( mapPoint );
|
||||||
|
if ( !mCenterPointRubberBand && mShowCenterPointRubberBand )
|
||||||
|
{
|
||||||
|
createCenterPointRubberBand();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( mPoints.size() > 1 )
|
||||||
|
{
|
||||||
|
if ( !mRubberBand )
|
||||||
|
{
|
||||||
|
mRubberBand = createGeometryRubberBand(( mCaptureMode == CapturePolygon ) ? QGis::Polygon : QGis::Line );
|
||||||
|
mRubberBand->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsCircularStringV2* c = new QgsCircularStringV2();
|
||||||
|
QList< QgsPointV2 > rubberBandPoints = mPoints;
|
||||||
|
rubberBandPoints.append( mapPoint );
|
||||||
|
c->setPoints( rubberBandPoints );
|
||||||
|
mRubberBand->setGeometry( c );
|
||||||
|
}
|
||||||
|
if (( mPoints.size() ) % 2 == 1 )
|
||||||
|
{
|
||||||
|
removeCenterPointRubberBand();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( e->button() == Qt::RightButton )
|
||||||
|
{
|
||||||
|
deactivate();
|
||||||
|
if ( mParentTool )
|
||||||
|
{
|
||||||
|
mParentTool->canvasReleaseEvent( e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsMapToolCircularStringCurvePoint::canvasMapMoveEvent( QgsMapMouseEvent* e )
|
||||||
|
{
|
||||||
|
QgsPointV2 mapPoint( e->mapPoint().x(), e->mapPoint().y() );
|
||||||
|
QgsVertexId idx; idx.part = 0; idx.ring = 0; idx.vertex = mPoints.size();
|
||||||
|
if ( mRubberBand )
|
||||||
|
{
|
||||||
|
mRubberBand->moveVertex( idx, mapPoint );
|
||||||
|
updateCenterPointRubberBand( mapPoint );
|
||||||
|
}
|
||||||
|
}
|
32
src/app/qgsmaptoolcircularstringcurvepoint.h
Normal file
32
src/app/qgsmaptoolcircularstringcurvepoint.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
qgsmaptoolcircularstringcurvepoint.h - map tool for adding circular
|
||||||
|
strings by start / curve / endpoint
|
||||||
|
---------------------
|
||||||
|
begin : Feb 2015
|
||||||
|
copyright : (C) 2015 by Marco Hugentobler
|
||||||
|
email : marco dot hugentobler at sourcepole dot ch
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QGSMAPTOOLCIRCULARSTRINGCURVEPOINT_H
|
||||||
|
#define QGSMAPTOOLCIRCULARSTRINGCURVEPOINT_H
|
||||||
|
|
||||||
|
#include "qgsmaptooladdcircularstring.h"
|
||||||
|
|
||||||
|
class QgsMapToolCircularStringCurvePoint: public QgsMapToolAddCircularString
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QgsMapToolCircularStringCurvePoint( QgsMapToolCapture* parentTool, QgsMapCanvas* canvas, CaptureMode mode = CaptureLine );
|
||||||
|
~QgsMapToolCircularStringCurvePoint();
|
||||||
|
|
||||||
|
void canvasMapReleaseEvent( QgsMapMouseEvent* e ) override;
|
||||||
|
void canvasMapMoveEvent( QgsMapMouseEvent* e ) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QGSMAPTOOLCIRCULARSTRINGCURVEPOINT_H
|
170
src/app/qgsmaptoolcircularstringradius.cpp
Normal file
170
src/app/qgsmaptoolcircularstringradius.cpp
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
qgsmaptoolcircularstringradius.h - map tool for adding circular strings
|
||||||
|
---------------------
|
||||||
|
begin : Feb 2015
|
||||||
|
copyright : (C) 2015 by Marco Hugentobler
|
||||||
|
email : marco dot hugentobler at sourcepole dot ch
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include "qgsmaptoolcircularstringradius.h"
|
||||||
|
#include "qgisapp.h"
|
||||||
|
#include "qgscircularstringv2.h"
|
||||||
|
#include "qgscompoundcurvev2.h"
|
||||||
|
#include "qgsgeometryutils.h"
|
||||||
|
#include "qgsgeometryrubberband.h"
|
||||||
|
#include "qgsmapcanvas.h"
|
||||||
|
#include "qgspointv2.h"
|
||||||
|
#include <QDoubleSpinBox>
|
||||||
|
#include <QMouseEvent>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
QgsMapToolCircularStringRadius::QgsMapToolCircularStringRadius( QgsMapToolCapture* parentTool, QgsMapCanvas* canvas, CaptureMode mode ) :
|
||||||
|
QgsMapToolAddCircularString( parentTool, canvas, mode ), mTemporaryEndPointX( 0.0 ), mTemporaryEndPointY( 0.0 ), mRadiusMode( false ), mRadius( 0.0 ),
|
||||||
|
mRadiusSpinBox( 0 )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsMapToolCircularStringRadius::~QgsMapToolCircularStringRadius()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsMapToolCircularStringRadius::canvasMapReleaseEvent( QgsMapMouseEvent* e )
|
||||||
|
{
|
||||||
|
QgsPointV2 mapPoint( e->mapPoint().x(), e->mapPoint().y() );
|
||||||
|
|
||||||
|
if ( e->button() == Qt::LeftButton )
|
||||||
|
{
|
||||||
|
if ( mPoints.size() == 0 )
|
||||||
|
{
|
||||||
|
//get first point from parent tool if there. Todo: move to upper class
|
||||||
|
const QgsCompoundCurveV2* compoundCurve = mParentTool->captureCurve();
|
||||||
|
if ( compoundCurve && compoundCurve->nCurves() > 0 )
|
||||||
|
{
|
||||||
|
const QgsCurveV2* curve = compoundCurve->curveAt( compoundCurve->nCurves() - 1 );
|
||||||
|
if ( curve )
|
||||||
|
{
|
||||||
|
//mParentTool->captureCurve() is in layer coordinates, but we need map coordinates
|
||||||
|
QgsPointV2 endPointLayerCoord = curve->endPoint();
|
||||||
|
QgsPoint mapPoint = toMapCoordinates( mCanvas->currentLayer(), QgsPoint( endPointLayerCoord.x(), endPointLayerCoord.y() ) );
|
||||||
|
mPoints.append( QgsPointV2( mapPoint.x(), mapPoint.y() ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mPoints.append( mapPoint );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( mPoints.size() % 2 == 1 )
|
||||||
|
{
|
||||||
|
if ( !mRadiusMode )
|
||||||
|
{
|
||||||
|
delete mRubberBand; mRubberBand = 0;
|
||||||
|
mTemporaryEndPointX = mapPoint.x();
|
||||||
|
mTemporaryEndPointY = mapPoint.y();
|
||||||
|
mRadiusMode = true;
|
||||||
|
|
||||||
|
//initial radius is distance( tempPoint - mPoints.last ) / 2.0
|
||||||
|
double minRadius = sqrt( QgsGeometryUtils::sqrDistance2D( mPoints.last(), QgsPointV2( mTemporaryEndPointX, mTemporaryEndPointY ) ) ) / 2.0;
|
||||||
|
mRadius = minRadius + minRadius / 10.0;
|
||||||
|
recalculateCircularString();
|
||||||
|
createRadiusSpinBox();
|
||||||
|
if ( mRadiusSpinBox )
|
||||||
|
{
|
||||||
|
mRadiusSpinBox->setMinimum( minRadius );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QgsPointV2 result;
|
||||||
|
if ( QgsGeometryUtils::segmentMidPoint( mPoints.last(), QgsPointV2( mTemporaryEndPointX, mTemporaryEndPointY ), result, mRadius, QgsPointV2( mapPoint.x(), mapPoint.y() ) ) )
|
||||||
|
{
|
||||||
|
mPoints.append( result );
|
||||||
|
mPoints.append( QgsPointV2( mTemporaryEndPointX, mTemporaryEndPointY ) );
|
||||||
|
}
|
||||||
|
mRadiusMode = false;
|
||||||
|
deleteRadiusSpinBox();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//can we get there?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( e->button() == Qt::RightButton )
|
||||||
|
{
|
||||||
|
deactivate();
|
||||||
|
if ( mParentTool )
|
||||||
|
{
|
||||||
|
mParentTool->canvasReleaseEvent( e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsMapToolCircularStringRadius::canvasMapMoveEvent( QgsMapMouseEvent* e )
|
||||||
|
{
|
||||||
|
if ( mPoints.size() > 0 && mRadiusMode )
|
||||||
|
{
|
||||||
|
mLastMouseMapPos.setX( e->mapPoint().x() );
|
||||||
|
mLastMouseMapPos.setY( e->mapPoint().y() );
|
||||||
|
recalculateCircularString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsMapToolCircularStringRadius::recalculateCircularString()
|
||||||
|
{
|
||||||
|
//new midpoint on circle segment
|
||||||
|
QgsPointV2 midPoint;
|
||||||
|
if ( !QgsGeometryUtils::segmentMidPoint( mPoints.last(), QgsPointV2( mTemporaryEndPointX, mTemporaryEndPointY ), midPoint, mRadius,
|
||||||
|
mLastMouseMapPos ) )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QgsPointV2> rubberBandPoints = mPoints; rubberBandPoints.append( midPoint ); rubberBandPoints.append( QgsPointV2( mTemporaryEndPointX, mTemporaryEndPointY ) );
|
||||||
|
QgsCircularStringV2* cString = new QgsCircularStringV2();
|
||||||
|
cString->setPoints( rubberBandPoints );
|
||||||
|
delete mRubberBand;
|
||||||
|
mRubberBand = createGeometryRubberBand(( mCaptureMode == CapturePolygon ) ? QGis::Polygon : QGis::Line );
|
||||||
|
mRubberBand->setGeometry( cString );
|
||||||
|
mRubberBand->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsMapToolCircularStringRadius::createRadiusSpinBox()
|
||||||
|
{
|
||||||
|
deleteRadiusSpinBox();
|
||||||
|
mRadiusSpinBox = new QDoubleSpinBox();
|
||||||
|
mRadiusSpinBox->setMaximum( 99999999 );
|
||||||
|
mRadiusSpinBox->setDecimals( 2 );
|
||||||
|
mRadiusSpinBox->setPrefix( tr( "Radius: " ) );
|
||||||
|
mRadiusSpinBox->setValue( mRadius );
|
||||||
|
QgisApp::instance()->addUserInputWidget( mRadiusSpinBox );
|
||||||
|
QObject::connect( mRadiusSpinBox, SIGNAL( valueChanged( double ) ), this, SLOT( updateRadiusFromSpinBox( double ) ) );
|
||||||
|
mRadiusSpinBox->setFocus( Qt::TabFocusReason );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsMapToolCircularStringRadius::deleteRadiusSpinBox()
|
||||||
|
{
|
||||||
|
if ( !mRadiusSpinBox )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QgisApp::instance()->statusBar()->removeWidget( mRadiusSpinBox );
|
||||||
|
delete mRadiusSpinBox; mRadiusSpinBox = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsMapToolCircularStringRadius::updateRadiusFromSpinBox( double radius )
|
||||||
|
{
|
||||||
|
mRadius = radius;
|
||||||
|
recalculateCircularString();
|
||||||
|
}
|
52
src/app/qgsmaptoolcircularstringradius.h
Normal file
52
src/app/qgsmaptoolcircularstringradius.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
qgsmaptoolcircularstringradius.h - map tool for adding circular strings
|
||||||
|
by two points and radius
|
||||||
|
---------------------
|
||||||
|
begin : Feb 2015
|
||||||
|
copyright : (C) 2015 by Marco Hugentobler
|
||||||
|
email : marco dot hugentobler at sourcepole dot ch
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QGSMAPTOOLCIRCULARSTRINGRADIUS_H
|
||||||
|
#define QGSMAPTOOLCIRCULARSTRINGRADIUS_H
|
||||||
|
|
||||||
|
#include "qgsmaptooladdcircularstring.h"
|
||||||
|
#include "qgspointv2.h"
|
||||||
|
|
||||||
|
class QDoubleSpinBox;
|
||||||
|
|
||||||
|
class QgsMapToolCircularStringRadius: public QgsMapToolAddCircularString
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
QgsMapToolCircularStringRadius( QgsMapToolCapture* parentTool, QgsMapCanvas* canvas, CaptureMode mode = CaptureLine );
|
||||||
|
~QgsMapToolCircularStringRadius();
|
||||||
|
|
||||||
|
virtual void canvasMapReleaseEvent( QgsMapMouseEvent* e ) override;
|
||||||
|
virtual void canvasMapMoveEvent( QgsMapMouseEvent* e ) override;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void updateRadiusFromSpinBox( double radius );
|
||||||
|
|
||||||
|
private:
|
||||||
|
double mTemporaryEndPointX;
|
||||||
|
double mTemporaryEndPointY;
|
||||||
|
bool mRadiusMode;
|
||||||
|
double mRadius;
|
||||||
|
QgsPointV2 mLastMouseMapPos;
|
||||||
|
QDoubleSpinBox* mRadiusSpinBox;
|
||||||
|
|
||||||
|
//recalculate circular string and rubber band depending on mRadius/mLeft and endpoints
|
||||||
|
void recalculateCircularString();
|
||||||
|
void createRadiusSpinBox();
|
||||||
|
void deleteRadiusSpinBox();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QGSMAPTOOLCIRCULARSTRINGRADIUS_H
|
@ -16,6 +16,7 @@
|
|||||||
#include "qgsmaptooledit.h"
|
#include "qgsmaptooledit.h"
|
||||||
#include "qgsproject.h"
|
#include "qgsproject.h"
|
||||||
#include "qgsmapcanvas.h"
|
#include "qgsmapcanvas.h"
|
||||||
|
#include "qgsgeometryrubberband.h"
|
||||||
#include "qgsrubberband.h"
|
#include "qgsrubberband.h"
|
||||||
#include "qgsvectorlayer.h"
|
#include "qgsvectorlayer.h"
|
||||||
|
|
||||||
@ -97,6 +98,21 @@ int QgsMapToolEdit::addTopologicalPoints( const QList<QgsPoint>& geom )
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QgsGeometryRubberBand* QgsMapToolEdit::createGeometryRubberBand( QGis::GeometryType geometryType ) const
|
||||||
|
{
|
||||||
|
QSettings settings;
|
||||||
|
QgsGeometryRubberBand* rb = new QgsGeometryRubberBand( mCanvas, geometryType );
|
||||||
|
QColor color( settings.value( "/qgis/digitizing/line_color_red", 255 ).toInt(),
|
||||||
|
settings.value( "/qgis/digitizing/line_color_green", 0 ).toInt(),
|
||||||
|
settings.value( "/qgis/digitizing/line_color_blue", 0 ).toInt() );
|
||||||
|
double myAlpha = settings.value( "/qgis/digitizing/line_color_alpha", 200 ).toInt() / 255.0 ;
|
||||||
|
color.setAlphaF( myAlpha );
|
||||||
|
rb->setOutlineColor( color );
|
||||||
|
rb->setFillColor( color );
|
||||||
|
rb->show();
|
||||||
|
return rb;
|
||||||
|
}
|
||||||
|
|
||||||
void QgsMapToolEdit::notifyNotVectorLayer()
|
void QgsMapToolEdit::notifyNotVectorLayer()
|
||||||
{
|
{
|
||||||
emit messageEmitted( tr( "No active vector layer" ) );
|
emit messageEmitted( tr( "No active vector layer" ) );
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "qgsmaptooladvanceddigitizing.h"
|
#include "qgsmaptooladvanceddigitizing.h"
|
||||||
|
|
||||||
class QgsRubberBand;
|
class QgsRubberBand;
|
||||||
|
class QgsGeometryRubberBand;
|
||||||
class QgsVectorLayer;
|
class QgsVectorLayer;
|
||||||
class QKeyEvent;
|
class QKeyEvent;
|
||||||
|
|
||||||
@ -44,6 +45,9 @@ class APP_EXPORT QgsMapToolEdit: public QgsMapToolAdvancedDigitizing
|
|||||||
*/
|
*/
|
||||||
QgsRubberBand* createRubberBand( QGis::GeometryType geometryType = QGis::Line, bool alternativeBand = false );
|
QgsRubberBand* createRubberBand( QGis::GeometryType geometryType = QGis::Line, bool alternativeBand = false );
|
||||||
|
|
||||||
|
|
||||||
|
QgsGeometryRubberBand* createGeometryRubberBand( QGis::GeometryType geometryType = QGis::Line ) const;
|
||||||
|
|
||||||
/** Returns the current vector layer of the map canvas or 0*/
|
/** Returns the current vector layer of the map canvas or 0*/
|
||||||
QgsVectorLayer* currentVectorLayer();
|
QgsVectorLayer* currentVectorLayer();
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ email : marco.hugentobler at sourcepole dot com
|
|||||||
#ifndef QGSABSTRACTGEOMETRYV2
|
#ifndef QGSABSTRACTGEOMETRYV2
|
||||||
#define QGSABSTRACTGEOMETRYV2
|
#define QGSABSTRACTGEOMETRYV2
|
||||||
|
|
||||||
|
#include "qgscoordinatetransform.h"
|
||||||
#include "qgsrectangle.h"
|
#include "qgsrectangle.h"
|
||||||
#include "qgswkbtypes.h"
|
#include "qgswkbtypes.h"
|
||||||
#include <QString>
|
#include <QString>
|
||||||
@ -216,8 +217,9 @@ class CORE_EXPORT QgsAbstractGeometryV2
|
|||||||
|
|
||||||
/** Transforms the geometry using a coordinate transform
|
/** Transforms the geometry using a coordinate transform
|
||||||
* @param ct coordinate transform
|
* @param ct coordinate transform
|
||||||
|
@param d transformation direction
|
||||||
*/
|
*/
|
||||||
virtual void transform( const QgsCoordinateTransform& ct ) = 0;
|
virtual void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform ) = 0;
|
||||||
|
|
||||||
/** Transforms the geometry using a QTransform object
|
/** Transforms the geometry using a QTransform object
|
||||||
* @param t QTransform transformation
|
* @param t QTransform transformation
|
||||||
|
@ -577,7 +577,7 @@ void QgsCircularStringV2::draw( QPainter& p ) const
|
|||||||
p.drawPath( path );
|
p.drawPath( path );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsCircularStringV2::transform( const QgsCoordinateTransform& ct )
|
void QgsCircularStringV2::transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d )
|
||||||
{
|
{
|
||||||
double* zArray = mZ.data();
|
double* zArray = mZ.data();
|
||||||
|
|
||||||
@ -591,7 +591,7 @@ void QgsCircularStringV2::transform( const QgsCoordinateTransform& ct )
|
|||||||
zArray[i] = 0;
|
zArray[i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ct.transformCoords( nPoints, mX.data(), mY.data(), zArray );
|
ct.transformCoords( nPoints, mX.data(), mY.data(), zArray, d );
|
||||||
if ( !hasZ )
|
if ( !hasZ )
|
||||||
{
|
{
|
||||||
delete[] zArray;
|
delete[] zArray;
|
||||||
|
@ -68,7 +68,11 @@ class CORE_EXPORT QgsCircularStringV2: public QgsCurveV2
|
|||||||
virtual QgsLineStringV2* curveToLine() const override;
|
virtual QgsLineStringV2* curveToLine() const override;
|
||||||
|
|
||||||
void draw( QPainter& p ) const override;
|
void draw( QPainter& p ) const override;
|
||||||
void transform( const QgsCoordinateTransform& ct ) override;
|
/** Transforms the geometry using a coordinate transform
|
||||||
|
* @param ct coordinate transform
|
||||||
|
@param d transformation direction
|
||||||
|
*/
|
||||||
|
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform ) override;
|
||||||
void transform( const QTransform& t ) override;
|
void transform( const QTransform& t ) override;
|
||||||
#if 0
|
#if 0
|
||||||
void clip( const QgsRectangle& rect ) override;
|
void clip( const QgsRectangle& rect ) override;
|
||||||
|
@ -410,12 +410,12 @@ void QgsCompoundCurveV2::draw( QPainter& p ) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsCompoundCurveV2::transform( const QgsCoordinateTransform& ct )
|
void QgsCompoundCurveV2::transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d )
|
||||||
{
|
{
|
||||||
QList< QgsCurveV2* >::iterator it = mCurves.begin();
|
QList< QgsCurveV2* >::iterator it = mCurves.begin();
|
||||||
for ( ; it != mCurves.end(); ++it )
|
for ( ; it != mCurves.end(); ++it )
|
||||||
{
|
{
|
||||||
( *it )->transform( ct );
|
( *it )->transform( ct, d );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +81,11 @@ class CORE_EXPORT QgsCompoundCurveV2: public QgsCurveV2
|
|||||||
void addVertex( const QgsPointV2& pt );
|
void addVertex( const QgsPointV2& pt );
|
||||||
|
|
||||||
void draw( QPainter& p ) const override;
|
void draw( QPainter& p ) const override;
|
||||||
void transform( const QgsCoordinateTransform& ct ) override;
|
/** Transforms the geometry using a coordinate transform
|
||||||
|
* @param ct coordinate transform
|
||||||
|
@param d transformation direction
|
||||||
|
*/
|
||||||
|
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform ) override;
|
||||||
void transform( const QTransform& t ) override;
|
void transform( const QTransform& t ) override;
|
||||||
void addToPainterPath( QPainterPath& path ) const override;
|
void addToPainterPath( QPainterPath& path ) const override;
|
||||||
void drawAsPolygon( QPainter& p ) const override;
|
void drawAsPolygon( QPainter& p ) const override;
|
||||||
|
@ -474,17 +474,17 @@ void QgsCurvePolygonV2::draw( QPainter& p ) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsCurvePolygonV2::transform( const QgsCoordinateTransform& ct )
|
void QgsCurvePolygonV2::transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d )
|
||||||
{
|
{
|
||||||
if ( mExteriorRing )
|
if ( mExteriorRing )
|
||||||
{
|
{
|
||||||
mExteriorRing->transform( ct );
|
mExteriorRing->transform( ct, d );
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QgsCurveV2*>::iterator it = mInteriorRings.begin();
|
QList<QgsCurveV2*>::iterator it = mInteriorRings.begin();
|
||||||
for ( ; it != mInteriorRings.end(); ++it )
|
for ( ; it != mInteriorRings.end(); ++it )
|
||||||
{
|
{
|
||||||
( *it )->transform( ct );
|
( *it )->transform( ct, d );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +76,11 @@ class CORE_EXPORT QgsCurvePolygonV2: public QgsSurfaceV2
|
|||||||
bool removeInteriorRing( int nr );
|
bool removeInteriorRing( int nr );
|
||||||
|
|
||||||
virtual void draw( QPainter& p ) const override;
|
virtual void draw( QPainter& p ) const override;
|
||||||
void transform( const QgsCoordinateTransform& ct ) override;
|
/** Transforms the geometry using a coordinate transform
|
||||||
|
* @param ct coordinate transform
|
||||||
|
@param d transformation direction
|
||||||
|
*/
|
||||||
|
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform ) override;
|
||||||
void transform( const QTransform& t ) override;
|
void transform( const QTransform& t ) override;
|
||||||
|
|
||||||
virtual bool insertVertex( const QgsVertexId& position, const QgsPointV2& vertex ) override;
|
virtual bool insertVertex( const QgsVertexId& position, const QgsPointV2& vertex ) override;
|
||||||
|
@ -130,12 +130,12 @@ int QgsGeometryCollectionV2::dimension() const
|
|||||||
return maxDim;
|
return maxDim;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsGeometryCollectionV2::transform( const QgsCoordinateTransform& ct )
|
void QgsGeometryCollectionV2::transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d )
|
||||||
{
|
{
|
||||||
QVector< QgsAbstractGeometryV2* >::iterator it = mGeometries.begin();
|
QVector< QgsAbstractGeometryV2* >::iterator it = mGeometries.begin();
|
||||||
for ( ; it != mGeometries.end(); ++it )
|
for ( ; it != mGeometries.end(); ++it )
|
||||||
{
|
{
|
||||||
( *it )->transform( ct );
|
( *it )->transform( ct, d );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +63,11 @@ class CORE_EXPORT QgsGeometryCollectionV2: public QgsAbstractGeometryV2
|
|||||||
*/
|
*/
|
||||||
virtual bool removeGeometry( int nr );
|
virtual bool removeGeometry( int nr );
|
||||||
|
|
||||||
virtual void transform( const QgsCoordinateTransform& ct ) override;
|
/** Transforms the geometry using a coordinate transform
|
||||||
|
* @param ct coordinate transform
|
||||||
|
@param d transformation direction
|
||||||
|
*/
|
||||||
|
virtual void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform ) override;
|
||||||
void transform( const QTransform& t ) override;
|
void transform( const QTransform& t ) override;
|
||||||
#if 0
|
#if 0
|
||||||
virtual void clip( const QgsRectangle& rect ) override;
|
virtual void clip( const QgsRectangle& rect ) override;
|
||||||
|
@ -333,9 +333,9 @@ void QgsLineStringV2::drawAsPolygon( QPainter& p ) const
|
|||||||
p.drawPolygon( mCoords );
|
p.drawPolygon( mCoords );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsLineStringV2::transform( const QgsCoordinateTransform& ct )
|
void QgsLineStringV2::transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d )
|
||||||
{
|
{
|
||||||
ct.transformPolygon( mCoords );
|
ct.transformPolygon( mCoords, d );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsLineStringV2::transform( const QTransform& t )
|
void QgsLineStringV2::transform( const QTransform& t )
|
||||||
|
@ -64,7 +64,12 @@ class CORE_EXPORT QgsLineStringV2: public QgsCurveV2
|
|||||||
void append( const QgsLineStringV2* line );
|
void append( const QgsLineStringV2* line );
|
||||||
|
|
||||||
void draw( QPainter& p ) const override;
|
void draw( QPainter& p ) const override;
|
||||||
void transform( const QgsCoordinateTransform& ct ) override;
|
|
||||||
|
/** Transforms the geometry using a coordinate transform
|
||||||
|
* @param ct coordinate transform
|
||||||
|
@param d transformation direction
|
||||||
|
*/
|
||||||
|
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform ) override;
|
||||||
void transform( const QTransform& t ) override;
|
void transform( const QTransform& t ) override;
|
||||||
|
|
||||||
void addToPainterPath( QPainterPath& path ) const override;
|
void addToPainterPath( QPainterPath& path ) const override;
|
||||||
|
@ -181,9 +181,9 @@ void QgsPointV2::clear()
|
|||||||
mX = mY = mZ = mM = 0.;
|
mX = mY = mZ = mM = 0.;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsPointV2::transform( const QgsCoordinateTransform& ct )
|
void QgsPointV2::transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d )
|
||||||
{
|
{
|
||||||
ct.transformInPlace( mX, mY, mZ );
|
ct.transformInPlace( mX, mY, mZ, d );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsPointV2::coordinateSequence( QList< QList< QList< QgsPointV2 > > >& coord ) const
|
void QgsPointV2::coordinateSequence( QList< QList< QList< QgsPointV2 > > >& coord ) const
|
||||||
|
@ -67,7 +67,12 @@ class CORE_EXPORT QgsPointV2: public QgsAbstractGeometryV2
|
|||||||
virtual QgsRectangle calculateBoundingBox() const override { return QgsRectangle( mX, mY, mX, mY );}
|
virtual QgsRectangle calculateBoundingBox() const override { return QgsRectangle( mX, mY, mX, mY );}
|
||||||
|
|
||||||
void draw( QPainter& p ) const override;
|
void draw( QPainter& p ) const override;
|
||||||
void transform( const QgsCoordinateTransform& ct ) override;
|
|
||||||
|
/** Transforms the geometry using a coordinate transform
|
||||||
|
* @param ct coordinate transform
|
||||||
|
@param d transformation direction
|
||||||
|
*/
|
||||||
|
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform ) override;
|
||||||
void transform( const QTransform& t ) override;
|
void transform( const QTransform& t ) override;
|
||||||
|
|
||||||
virtual void coordinateSequence( QList< QList< QList< QgsPointV2 > > >& coord ) const override;
|
virtual void coordinateSequence( QList< QList< QList< QgsPointV2 > > >& coord ) const override;
|
||||||
|
@ -94,7 +94,9 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider
|
|||||||
/** Supports topological simplification of geometries on provider side according to a distance tolerance */
|
/** Supports topological simplification of geometries on provider side according to a distance tolerance */
|
||||||
SimplifyGeometriesWithTopologicalValidation = 1 << 15,
|
SimplifyGeometriesWithTopologicalValidation = 1 << 15,
|
||||||
/** Supports transactions*/
|
/** Supports transactions*/
|
||||||
TransactionSupport = 1 << 16
|
TransactionSupport = 1 << 16,
|
||||||
|
/** Supports circular geometry types (circularstring, compoundcurve, curvepolygon)*/
|
||||||
|
CircularGeometries = 1 << 17
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Bitmask of all provider's editing capabilities */
|
/** Bitmask of all provider's editing capabilities */
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#include "qgsclipper.h"
|
#include "qgsclipper.h"
|
||||||
#include "qgscoordinatereferencesystem.h"
|
#include "qgscoordinatereferencesystem.h"
|
||||||
#include "qgscoordinatetransform.h"
|
#include "qgscoordinatetransform.h"
|
||||||
|
#include "qgscurvev2.h"
|
||||||
#include "qgsdatasourceuri.h"
|
#include "qgsdatasourceuri.h"
|
||||||
#include "qgsexpressionfieldbuffer.h"
|
#include "qgsexpressionfieldbuffer.h"
|
||||||
#include "qgsfeature.h"
|
#include "qgsfeature.h"
|
||||||
@ -1043,6 +1044,27 @@ int QgsVectorLayer::addRing( const QList<QgsPoint>& ring )
|
|||||||
return utils.addRing( ring );
|
return utils.addRing( ring );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int QgsVectorLayer::addRing( QgsCurveV2* ring )
|
||||||
|
{
|
||||||
|
if ( !mEditBuffer || !mDataProvider )
|
||||||
|
{
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !ring )
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !ring->isClosed() )
|
||||||
|
{
|
||||||
|
delete ring; return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsVectorLayerEditUtils utils( this );
|
||||||
|
return utils.addRing( ring );
|
||||||
|
}
|
||||||
|
|
||||||
int QgsVectorLayer::addPart( const QList<QgsPoint> &points )
|
int QgsVectorLayer::addPart( const QList<QgsPoint> &points )
|
||||||
{
|
{
|
||||||
if ( !mEditBuffer || !mDataProvider )
|
if ( !mEditBuffer || !mDataProvider )
|
||||||
@ -1065,6 +1087,27 @@ int QgsVectorLayer::addPart( const QList<QgsPoint> &points )
|
|||||||
return utils.addPart( points, *mSelectedFeatureIds.constBegin() );
|
return utils.addPart( points, *mSelectedFeatureIds.constBegin() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int QgsVectorLayer::addPart( QgsCurveV2* ring )
|
||||||
|
{
|
||||||
|
if ( !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( ring, *mSelectedFeatureIds.constBegin() );
|
||||||
|
}
|
||||||
|
|
||||||
int QgsVectorLayer::translateFeature( QgsFeatureId featureId, double dx, double dy )
|
int QgsVectorLayer::translateFeature( QgsFeatureId featureId, double dx, double dy )
|
||||||
{
|
{
|
||||||
@ -2229,7 +2272,7 @@ bool QgsVectorLayer::deleteAttributes( QList<int> attrs )
|
|||||||
|
|
||||||
qSort( attrs.begin(), attrs.end(), qGreater<int>() );
|
qSort( attrs.begin(), attrs.end(), qGreater<int>() );
|
||||||
|
|
||||||
Q_FOREACH ( int attr, attrs )
|
Q_FOREACH( int attr, attrs )
|
||||||
{
|
{
|
||||||
if ( deleteAttribute( attr ) )
|
if ( deleteAttribute( attr ) )
|
||||||
{
|
{
|
||||||
@ -2988,7 +3031,7 @@ void QgsVectorLayer::uniqueValues( int index, QList<QVariant> &uniqueValues, int
|
|||||||
if ( mEditBuffer )
|
if ( mEditBuffer )
|
||||||
{
|
{
|
||||||
QSet<QString> vals;
|
QSet<QString> vals;
|
||||||
Q_FOREACH ( const QVariant& v, uniqueValues )
|
Q_FOREACH( const QVariant& v, uniqueValues )
|
||||||
{
|
{
|
||||||
vals << v.toString();
|
vals << v.toString();
|
||||||
}
|
}
|
||||||
@ -3818,7 +3861,7 @@ void QgsVectorLayer::invalidateSymbolCountedFlag()
|
|||||||
|
|
||||||
void QgsVectorLayer::onRelationsLoaded()
|
void QgsVectorLayer::onRelationsLoaded()
|
||||||
{
|
{
|
||||||
Q_FOREACH ( QgsAttributeEditorElement* elem, mAttributeEditorElements )
|
Q_FOREACH( QgsAttributeEditorElement* elem, mAttributeEditorElements )
|
||||||
{
|
{
|
||||||
if ( elem->type() == QgsAttributeEditorElement::AeTypeContainer )
|
if ( elem->type() == QgsAttributeEditorElement::AeTypeContainer )
|
||||||
{
|
{
|
||||||
@ -3827,7 +3870,7 @@ void QgsVectorLayer::onRelationsLoaded()
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
QList<QgsAttributeEditorElement*> relations = cont->findElements( QgsAttributeEditorElement::AeTypeRelation );
|
QList<QgsAttributeEditorElement*> relations = cont->findElements( QgsAttributeEditorElement::AeTypeRelation );
|
||||||
Q_FOREACH ( QgsAttributeEditorElement* relElem, relations )
|
Q_FOREACH( QgsAttributeEditorElement* relElem, relations )
|
||||||
{
|
{
|
||||||
QgsAttributeEditorRelation* rel = dynamic_cast< QgsAttributeEditorRelation* >( relElem );
|
QgsAttributeEditorRelation* rel = dynamic_cast< QgsAttributeEditorRelation* >( relElem );
|
||||||
if ( !rel )
|
if ( !rel )
|
||||||
@ -3896,7 +3939,7 @@ QDomElement QgsAttributeEditorContainer::toDomElement( QDomDocument& doc ) const
|
|||||||
QDomElement elem = doc.createElement( "attributeEditorContainer" );
|
QDomElement elem = doc.createElement( "attributeEditorContainer" );
|
||||||
elem.setAttribute( "name", mName );
|
elem.setAttribute( "name", mName );
|
||||||
|
|
||||||
Q_FOREACH ( QgsAttributeEditorElement* child, mChildren )
|
Q_FOREACH( QgsAttributeEditorElement* child, mChildren )
|
||||||
{
|
{
|
||||||
elem.appendChild( child->toDomElement( doc ) );
|
elem.appendChild( child->toDomElement( doc ) );
|
||||||
}
|
}
|
||||||
@ -3917,7 +3960,7 @@ QList<QgsAttributeEditorElement*> QgsAttributeEditorContainer::findElements( Qgs
|
|||||||
{
|
{
|
||||||
QList<QgsAttributeEditorElement*> results;
|
QList<QgsAttributeEditorElement*> results;
|
||||||
|
|
||||||
Q_FOREACH ( QgsAttributeEditorElement* elem, mChildren )
|
Q_FOREACH( QgsAttributeEditorElement* elem, mChildren )
|
||||||
{
|
{
|
||||||
if ( elem->type() == type )
|
if ( elem->type() == type )
|
||||||
{
|
{
|
||||||
|
@ -42,6 +42,7 @@ class QgsAbstractGeometrySimplifier;
|
|||||||
class QgsAttributeAction;
|
class QgsAttributeAction;
|
||||||
class QgsFieldUIProperties;
|
class QgsFieldUIProperties;
|
||||||
class QgsCoordinateTransform;
|
class QgsCoordinateTransform;
|
||||||
|
class QgsCurveV2;
|
||||||
class QgsDiagramLayerSettings;
|
class QgsDiagramLayerSettings;
|
||||||
class QgsDiagramRendererV2;
|
class QgsDiagramRendererV2;
|
||||||
class QgsEditorWidgetWrapper;
|
class QgsEditorWidgetWrapper;
|
||||||
@ -1170,6 +1171,14 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
|
|||||||
6 layer not editable */
|
6 layer not editable */
|
||||||
int addRing( const QList<QgsPoint>& ring );
|
int addRing( const QList<QgsPoint>& ring );
|
||||||
|
|
||||||
|
/** Adds a ring to polygon/multipolygon features (takes ownership)
|
||||||
|
@return
|
||||||
|
0 in case of success
|
||||||
|
1 problem with feature type
|
||||||
|
2 ring not closed
|
||||||
|
6 layer not editable*/
|
||||||
|
int addRing( QgsCurveV2* ring );
|
||||||
|
|
||||||
/** Adds a new part polygon to a multipart feature
|
/** Adds a new part polygon to a multipart feature
|
||||||
@return
|
@return
|
||||||
0 in case of success,
|
0 in case of success,
|
||||||
@ -1182,6 +1191,8 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
|
|||||||
7 layer not editable */
|
7 layer not editable */
|
||||||
int addPart( const QList<QgsPoint>& ring );
|
int addPart( const QList<QgsPoint>& ring );
|
||||||
|
|
||||||
|
int addPart( QgsCurveV2* ring );
|
||||||
|
|
||||||
/** Translates feature by dx, dy
|
/** Translates feature by dx, dy
|
||||||
@param featureId id of the feature to translate
|
@param featureId id of the feature to translate
|
||||||
@param dx translation of x-coordinate
|
@param dx translation of x-coordinate
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "qgsvectordataprovider.h"
|
#include "qgsvectordataprovider.h"
|
||||||
#include "qgsgeometrycache.h"
|
#include "qgsgeometrycache.h"
|
||||||
#include "qgsvectorlayereditbuffer.h"
|
#include "qgsvectorlayereditbuffer.h"
|
||||||
|
#include "qgslinestringv2.h"
|
||||||
#include "qgslogger.h"
|
#include "qgslogger.h"
|
||||||
#include "qgspointv2.h"
|
#include "qgspointv2.h"
|
||||||
|
|
||||||
@ -103,26 +104,26 @@ bool QgsVectorLayerEditUtils::deleteVertex( QgsFeatureId atFeatureId, int atVert
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int QgsVectorLayerEditUtils::addRing( const QList<QgsPoint>& ring )
|
int QgsVectorLayerEditUtils::addRing( const QList<QgsPoint>& ring )
|
||||||
|
{
|
||||||
|
QgsLineStringV2* ringLine = new QgsLineStringV2();
|
||||||
|
QList< QgsPointV2 > ringPoints;
|
||||||
|
QList<QgsPoint>::const_iterator ringIt = ring.constBegin();
|
||||||
|
for ( ; ringIt != ring.constEnd(); ++ringIt )
|
||||||
|
{
|
||||||
|
ringPoints.append( QgsPointV2( ringIt->x(), ringIt->y() ) );
|
||||||
|
}
|
||||||
|
ringLine->setPoints( ringPoints );
|
||||||
|
return addRing( ringLine );
|
||||||
|
}
|
||||||
|
|
||||||
|
int QgsVectorLayerEditUtils::addRing( QgsCurveV2* ring )
|
||||||
{
|
{
|
||||||
if ( !L->hasGeometryType() )
|
if ( !L->hasGeometryType() )
|
||||||
return 5;
|
return 5;
|
||||||
|
|
||||||
int addRingReturnCode = 5; //default: return code for 'ring not inserted'
|
int addRingReturnCode = 5; //default: return code for 'ring not inserted'
|
||||||
double xMin, yMin, xMax, yMax;
|
QgsRectangle bBox = ring->boundingBox();
|
||||||
QgsRectangle bBox;
|
|
||||||
|
|
||||||
if ( boundingBoxFromPointList( ring, xMin, yMin, xMax, yMax ) == 0 )
|
|
||||||
{
|
|
||||||
bBox.setXMinimum( xMin ); bBox.setYMinimum( yMin );
|
|
||||||
bBox.setXMaximum( xMax ); bBox.setYMaximum( yMax );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 3; //ring not valid
|
|
||||||
}
|
|
||||||
|
|
||||||
QgsFeatureIterator fit = L->getFeatures( QgsFeatureRequest().setFilterRect( bBox ).setFlags( QgsFeatureRequest::ExactIntersect ) );
|
QgsFeatureIterator fit = L->getFeatures( QgsFeatureRequest().setFilterRect( bBox ).setFlags( QgsFeatureRequest::ExactIntersect ) );
|
||||||
|
|
||||||
QgsFeature f;
|
QgsFeature f;
|
||||||
@ -141,7 +142,6 @@ int QgsVectorLayerEditUtils::addRing( const QList<QgsPoint>& ring )
|
|||||||
return addRingReturnCode;
|
return addRingReturnCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int QgsVectorLayerEditUtils::addPart( const QList<QgsPoint> &points, QgsFeatureId featureId )
|
int QgsVectorLayerEditUtils::addPart( const QList<QgsPoint> &points, QgsFeatureId featureId )
|
||||||
{
|
{
|
||||||
if ( !L->hasGeometryType() )
|
if ( !L->hasGeometryType() )
|
||||||
@ -152,10 +152,10 @@ int QgsVectorLayerEditUtils::addPart( const QList<QgsPoint> &points, QgsFeatureI
|
|||||||
{
|
{
|
||||||
// it's not in cache: let's fetch it from layer
|
// it's not in cache: let's fetch it from layer
|
||||||
QgsFeature f;
|
QgsFeature f;
|
||||||
if ( !L->getFeatures( QgsFeatureRequest().setFilterFid( featureId ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( f ) || !f.constGeometry() )
|
if ( !L->getFeatures( QgsFeatureRequest().setFilterFid( featureId ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( f ) || !f.geometry() )
|
||||||
return 6; //geometry not found
|
return 6; //geometry not found
|
||||||
|
|
||||||
geometry = *f.constGeometry();
|
geometry = *f.geometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
int errorCode = geometry.addPart( points, L->geometryType() );
|
int errorCode = geometry.addPart( points, L->geometryType() );
|
||||||
@ -166,6 +166,29 @@ int QgsVectorLayerEditUtils::addPart( const QList<QgsPoint> &points, QgsFeatureI
|
|||||||
return errorCode;
|
return errorCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int QgsVectorLayerEditUtils::addPart( QgsCurveV2* ring, QgsFeatureId featureId )
|
||||||
|
{
|
||||||
|
if ( !L->hasGeometryType() )
|
||||||
|
return 6;
|
||||||
|
|
||||||
|
QgsGeometry geometry;
|
||||||
|
if ( !cache()->geometry( featureId, geometry ) ) // maybe it's in cache
|
||||||
|
{
|
||||||
|
// it's not in cache: let's fetch it from layer
|
||||||
|
QgsFeature f;
|
||||||
|
if ( !L->getFeatures( QgsFeatureRequest().setFilterFid( featureId ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( f ) || !f.geometry() )
|
||||||
|
return 6; //geometry not found
|
||||||
|
|
||||||
|
geometry = *f.geometry();
|
||||||
|
}
|
||||||
|
|
||||||
|
int errorCode = geometry.addPart( ring );
|
||||||
|
if ( errorCode == 0 )
|
||||||
|
{
|
||||||
|
L->editBuffer()->changeGeometry( featureId, &geometry );
|
||||||
|
}
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int QgsVectorLayerEditUtils::translateFeature( QgsFeatureId featureId, double dx, double dy )
|
int QgsVectorLayerEditUtils::translateFeature( QgsFeatureId featureId, double dx, double dy )
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "qgsvectorlayer.h"
|
#include "qgsvectorlayer.h"
|
||||||
|
|
||||||
class QgsGeometryCache;
|
class QgsGeometryCache;
|
||||||
|
class QgsCurveV2;
|
||||||
|
|
||||||
class CORE_EXPORT QgsVectorLayerEditUtils
|
class CORE_EXPORT QgsVectorLayerEditUtils
|
||||||
{
|
{
|
||||||
@ -62,6 +63,16 @@ class CORE_EXPORT QgsVectorLayerEditUtils
|
|||||||
5 no feature found where ring can be inserted*/
|
5 no feature found where ring can be inserted*/
|
||||||
int addRing( const QList<QgsPoint>& ring );
|
int addRing( const QList<QgsPoint>& ring );
|
||||||
|
|
||||||
|
/** Adds a ring to polygon/multipolygon features
|
||||||
|
@return
|
||||||
|
0 in case of success,
|
||||||
|
1 problem with feature type,
|
||||||
|
2 ring not closed,
|
||||||
|
3 ring not valid,
|
||||||
|
4 ring crosses existing rings,
|
||||||
|
5 no feature found where ring can be inserted*/
|
||||||
|
int addRing( QgsCurveV2* ring );
|
||||||
|
|
||||||
/** Adds a new part polygon to a multipart feature
|
/** Adds a new part polygon to a multipart feature
|
||||||
@return
|
@return
|
||||||
0 in case of success,
|
0 in case of success,
|
||||||
@ -73,6 +84,8 @@ class CORE_EXPORT QgsVectorLayerEditUtils
|
|||||||
6 if selected geometry not found*/
|
6 if selected geometry not found*/
|
||||||
int addPart( const QList<QgsPoint>& ring, QgsFeatureId featureId );
|
int addPart( const QList<QgsPoint>& ring, QgsFeatureId featureId );
|
||||||
|
|
||||||
|
int addPart( QgsCurveV2* ring, QgsFeatureId featureId );
|
||||||
|
|
||||||
/** Translates feature by dx, dy
|
/** Translates feature by dx, dy
|
||||||
@param featureId id of the feature to translate
|
@param featureId id of the feature to translate
|
||||||
@param dx translation of x-coordinate
|
@param dx translation of x-coordinate
|
||||||
|
@ -1095,6 +1095,9 @@ bool QgsPostgresProvider::hasSufficientPermsAndCapabilities()
|
|||||||
|
|
||||||
//supports transactions
|
//supports transactions
|
||||||
mEnabledCapabilities |= QgsVectorDataProvider::TransactionSupport;
|
mEnabledCapabilities |= QgsVectorDataProvider::TransactionSupport;
|
||||||
|
|
||||||
|
// supports circular geometries
|
||||||
|
mEnabledCapabilities |= QgsVectorDataProvider::CircularGeometries;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>1050</width>
|
<width>1050</width>
|
||||||
<height>25</height>
|
<height>20</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
@ -356,6 +356,8 @@
|
|||||||
<addaction name="mActionToggleEditing"/>
|
<addaction name="mActionToggleEditing"/>
|
||||||
<addaction name="mActionSaveLayerEdits"/>
|
<addaction name="mActionSaveLayerEdits"/>
|
||||||
<addaction name="mActionAddFeature"/>
|
<addaction name="mActionAddFeature"/>
|
||||||
|
<addaction name="mActionCircularStringCurvePoint"/>
|
||||||
|
<addaction name="mActionCircularStringRadius"/>
|
||||||
<addaction name="mActionMoveFeature"/>
|
<addaction name="mActionMoveFeature"/>
|
||||||
<addaction name="mActionNodeTool"/>
|
<addaction name="mActionNodeTool"/>
|
||||||
<addaction name="mActionDeleteSelected"/>
|
<addaction name="mActionDeleteSelected"/>
|
||||||
@ -2352,6 +2354,30 @@ Acts on currently active editable layer</string>
|
|||||||
<string>Align Rasters...</string>
|
<string>Align Rasters...</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="mActionCircularStringCurvePoint">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../images/images.qrc">
|
||||||
|
<normaloff>:/images/themes/default/mActionCircularStringCurvePoint.png</normaloff>:/images/themes/default/mActionCircularStringCurvePoint.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Add circular string</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="mActionCircularStringRadius">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../images/images.qrc">
|
||||||
|
<normaloff>:/images/themes/default/mActionCircularStringRadius.png</normaloff>:/images/themes/default/mActionCircularStringRadius.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Add circular string by radius</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../../images/images.qrc"/>
|
<include location="../../images/images.qrc"/>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user