[QGIS Commit] r10700 - in trunk/qgis: images/themes/default
python/core src/app src/core src/ui
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Sat May 2 11:37:35 EDT 2009
Author: wonder
Date: 2009-05-02 11:37:35 -0400 (Sat, 02 May 2009)
New Revision: 10700
Added:
trunk/qgis/images/themes/default/mActionDeleteHole.png
trunk/qgis/images/themes/default/mActionDeletePart.png
trunk/qgis/images/themes/default/mActionSimplify.png
trunk/qgis/src/app/qgsmaptooldeletehole.cpp
trunk/qgis/src/app/qgsmaptooldeletehole.h
trunk/qgis/src/app/qgsmaptooldeletepart.cpp
trunk/qgis/src/app/qgsmaptooldeletepart.h
trunk/qgis/src/app/qgsmaptoolsimplify.cpp
trunk/qgis/src/app/qgsmaptoolsimplify.h
trunk/qgis/src/ui/qgssimplifytolerancedialog.ui
Modified:
trunk/qgis/python/core/qgsgeometry.sip
trunk/qgis/src/app/CMakeLists.txt
trunk/qgis/src/app/qgisapp.cpp
trunk/qgis/src/app/qgisapp.h
trunk/qgis/src/core/qgsgeometry.cpp
trunk/qgis/src/core/qgsgeometry.h
Log:
New vector editing tools:
- delete part of multipart feature
- delete hole from polygon
- simplify feature
These tools are in the new "advanced" editing toolbar.
Contributed by Richard Kostecky (qgis-mapper project).
Added: trunk/qgis/images/themes/default/mActionDeleteHole.png
===================================================================
(Binary files differ)
Property changes on: trunk/qgis/images/themes/default/mActionDeleteHole.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/qgis/images/themes/default/mActionDeletePart.png
===================================================================
(Binary files differ)
Property changes on: trunk/qgis/images/themes/default/mActionDeletePart.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/qgis/images/themes/default/mActionSimplify.png
===================================================================
(Binary files differ)
Property changes on: trunk/qgis/images/themes/default/mActionSimplify.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Modified: trunk/qgis/python/core/qgsgeometry.sip
===================================================================
--- trunk/qgis/python/core/qgsgeometry.sip 2009-05-02 14:27:25 UTC (rev 10699)
+++ trunk/qgis/python/core/qgsgeometry.sip 2009-05-02 15:37:35 UTC (rev 10700)
@@ -289,5 +289,16 @@
// TODO: destruction of created geometries??
QList<QgsGeometry*> asGeometryCollection() /Factory/;
+ /** delete a hole in polygon or multipolygon.
+ Ring 0 is outer ring and can't be deleted.
+ @return TRUE on success
+ @note added in version 1.2 */
+ bool deleteHole( int ringNum, int partNum = 0 );
+
+ /** delete part identified by the part number
+ @return TRUE on success
+ @note added in version 1.2 */
+ bool deletePart( int partNum );
+
}; // class QgsGeometry
Modified: trunk/qgis/src/app/CMakeLists.txt
===================================================================
--- trunk/qgis/src/app/CMakeLists.txt 2009-05-02 14:27:25 UTC (rev 10699)
+++ trunk/qgis/src/app/CMakeLists.txt 2009-05-02 15:37:35 UTC (rev 10700)
@@ -27,12 +27,15 @@
qgsmaptooladdisland.cpp
qgsmaptooladdring.cpp
qgsmaptoolcapture.cpp
+ qgsmaptooldeletehole.cpp
+ qgsmaptooldeletepart.cpp
qgsmaptooldeletevertex.cpp
qgsmaptooledit.cpp
qgsmaptoolidentify.cpp
qgsmaptoolmovefeature.cpp
qgsmaptoolmovevertex.cpp
qgsmaptoolselect.cpp
+ qgsmaptoolsimplify.cpp
qgsmaptoolsplitfeatures.cpp
qgsmaptoolvertexedit.cpp
qgsmeasuredialog.cpp
@@ -115,6 +118,7 @@
qgsmaptooladdring.h
qgsmaptoolmovefeature.h
qgsmaptoolselect.h
+ qgsmaptoolsimplify.h
qgsmeasuretool.h
qgsmeasuredialog.h
Modified: trunk/qgis/src/app/qgisapp.cpp
===================================================================
--- trunk/qgis/src/app/qgisapp.cpp 2009-05-02 14:27:25 UTC (rev 10699)
+++ trunk/qgis/src/app/qgisapp.cpp 2009-05-02 15:37:35 UTC (rev 10700)
@@ -157,6 +157,8 @@
#include "qgsmaptooladdisland.h"
#include "qgsmaptooladdring.h"
#include "qgsmaptooladdvertex.h"
+#include "qgsmaptooldeletehole.h"
+#include "qgsmaptooldeletepart.h"
#include "qgsmaptooldeletevertex.h"
#include "qgsmaptoolidentify.h"
#include "qgsmaptoolmovefeature.h"
@@ -166,6 +168,7 @@
#include "qgsmaptoolsplitfeatures.h"
#include "qgsmaptoolvertexedit.h"
#include "qgsmaptoolzoom.h"
+#include "qgsmaptoolsimplify.h"
#include "qgsmeasuretool.h"
//
@@ -465,6 +468,9 @@
delete mMapTools.mVertexMove;
delete mMapTools.mVertexDelete;
delete mMapTools.mAddRing;
+ delete mMapTools.mSimplifyFeature;
+ delete mMapTools.mDeleteHole;
+ delete mMapTools.mDeletePart;
delete mMapTools.mAddIsland;
delete mPythonConsole;
@@ -667,6 +673,22 @@
connect( mActionAddIsland, SIGNAL( triggered() ), this, SLOT( addIsland() ) );
mActionAddIsland->setEnabled( false );
+ mActionSimplifyFeature = new QAction( getThemeIcon( "mActionSimplify.png" ), tr( "Simplify Feature" ), this );
+ mActionSimplifyFeature->setStatusTip( tr( "Simplify Feature" ) );
+ connect( mActionSimplifyFeature, SIGNAL( triggered() ), this, SLOT( simplifyFeature() ) );
+ mActionSimplifyFeature->setEnabled( false );
+
+ mActionDeleteHole = new QAction( getThemeIcon( "mActionDeleteHole.png" ), tr( "Delete Hole" ), this );
+ mActionDeleteHole->setStatusTip( tr( "Delete Hole" ) );
+ connect( mActionDeleteHole, SIGNAL( triggered() ), this, SLOT( deleteHole() ) );
+ mActionDeleteHole->setEnabled( false );
+
+ mActionDeletePart = new QAction( getThemeIcon( "mActionDeletePart.png" ), tr( "Delete Part" ), this );
+ mActionDeletePart->setStatusTip( tr( "Delete Part" ) );
+ connect( mActionDeletePart, SIGNAL( triggered() ), this, SLOT( deletePart() ) );
+ mActionDeletePart->setEnabled( false );
+
+
// View Menu Items
mActionPan = new QAction( getThemeIcon( "mActionPan.png" ), tr( "Pan Map" ), this );
@@ -990,6 +1012,12 @@
mMapToolGroup->addAction( mActionAddRing );
mActionAddIsland->setCheckable( true );
mMapToolGroup->addAction( mActionAddIsland );
+ mActionSimplifyFeature->setCheckable( true );
+ mMapToolGroup->addAction( mActionSimplifyFeature );
+ mActionDeleteHole->setCheckable( true );
+ mMapToolGroup->addAction( mActionDeleteHole );
+ mActionDeletePart->setCheckable( true );
+ mMapToolGroup->addAction( mActionDeletePart );
}
void QgisApp::createMenus()
@@ -1073,9 +1101,15 @@
mEditMenu->addAction( mActionAddRing );
mEditMenu->addAction( mActionAddIsland );
+ mActionEditSeparator2 = mEditMenu->addSeparator();
+
+ mEditMenu->addAction( mActionSimplifyFeature );
+ mEditMenu->addAction( mActionDeleteHole );
+ mEditMenu->addAction( mActionDeletePart );
+
if ( layout == QDialogButtonBox::GnomeLayout || layout == QDialogButtonBox::MacLayout )
{
- mActionEditSeparator2 = mEditMenu->addSeparator();
+ mActionEditSeparator3 = mEditMenu->addSeparator();
mEditMenu->addAction( mActionOptions );
mEditMenu->addAction( mActionCustomProjection );
}
@@ -1267,6 +1301,16 @@
mDigitizeToolBar->addAction( mActionCopyFeatures );
mDigitizeToolBar->addAction( mActionPasteFeatures );
mToolbarMenu->addAction( mDigitizeToolBar->toggleViewAction() );
+
+ mAdvancedDigitizeToolBar = addToolBar( tr( "Advanced Digitizing" ) );
+ mAdvancedDigitizeToolBar->setIconSize( myIconSize );
+ mAdvancedDigitizeToolBar->setObjectName( "Advanced Digitizing" );
+ mAdvancedDigitizeToolBar->addAction( mActionSimplifyFeature );
+ mAdvancedDigitizeToolBar->addAction( mActionDeleteHole );
+ mAdvancedDigitizeToolBar->addAction( mActionDeletePart );
+ mToolbarMenu->addAction( mAdvancedDigitizeToolBar->toggleViewAction() );
+
+
//
// Map Navigation Toolbar
mMapNavToolBar = addToolBar( tr( "Map Navigation" ) );
@@ -1606,6 +1650,12 @@
mMapTools.mAddRing = new QgsMapToolAddRing( mMapCanvas );
mMapTools.mAddRing->setAction( mActionAddRing );
mMapTools.mAddIsland = new QgsMapToolAddIsland( mMapCanvas );
+ mMapTools.mSimplifyFeature = new QgsMapToolSimplify( mMapCanvas );
+ mMapTools.mSimplifyFeature->setAction( mActionSimplifyFeature );
+ mMapTools.mDeleteHole = new QgsMapToolDeleteHole( mMapCanvas );
+ mMapTools.mDeleteHole->setAction( mActionDeleteHole );
+ mMapTools.mDeletePart = new QgsMapToolDeletePart( mMapCanvas );
+ mMapTools.mDeletePart->setAction( mActionDeletePart );
//ensure that non edit tool is initialised or we will get crashes in some situations
mNonEditMapTool = mMapTools.mPan;
}
@@ -3979,6 +4029,21 @@
mMapCanvas->setMapTool( mMapTools.mMoveFeature );
}
+void QgisApp::simplifyFeature()
+{
+ mMapCanvas->setMapTool( mMapTools.mSimplifyFeature );
+}
+
+void QgisApp::deleteHole()
+{
+ mMapCanvas->setMapTool( mMapTools.mDeleteHole );
+}
+
+void QgisApp::deletePart()
+{
+ mMapCanvas->setMapTool( mMapTools.mDeletePart );
+}
+
void QgisApp::splitFeatures()
{
mMapCanvas->setMapTool( mMapTools.mSplitFeatures );
@@ -5215,11 +5280,13 @@
{
mActionCapturePoint->setEnabled( true );
mActionCapturePoint->setVisible( true );
+ mActionDeletePart->setEnabled( true );
}
else
{
mActionCapturePoint->setEnabled( false );
mActionCapturePoint->setVisible( false );
+ mActionDeletePart->setEnabled( false );
}
mActionCaptureLine->setEnabled( false );
mActionCapturePolygon->setEnabled( false );
@@ -5231,6 +5298,9 @@
mActionAddRing->setEnabled( false );
mActionAddIsland->setEnabled( false );
mActionSplitFeatures->setEnabled( false );
+ mActionSimplifyFeature->setEnabled( false );
+ mActionDeleteHole->setEnabled( false );
+
if ( vlayer->isEditable() && dprovider->capabilities() & QgsVectorDataProvider::ChangeGeometries )
{
mActionMoveVertex->setEnabled( true );
@@ -5244,12 +5314,16 @@
mActionCaptureLine->setEnabled( true );
mActionCaptureLine->setVisible( true );
mActionSplitFeatures->setEnabled( true );
+ mActionSimplifyFeature->setEnabled( true );
+ mActionDeletePart->setEnabled( true );
}
else
{
mActionCaptureLine->setEnabled( false );
mActionCaptureLine->setVisible( false );
mActionSplitFeatures->setEnabled( false );
+ mActionSimplifyFeature->setEnabled( false );
+ mActionDeletePart->setEnabled( false );
}
mActionCapturePoint->setEnabled( false );
mActionCapturePolygon->setEnabled( false );
@@ -5257,6 +5331,7 @@
mActionCapturePolygon->setVisible( false );
mActionAddRing->setEnabled( false );
mActionAddIsland->setEnabled( false );
+ mActionDeleteHole->setEnabled( false );
}
else if ( vlayer->geometryType() == QGis::Polygon )
{
@@ -5267,6 +5342,9 @@
mActionAddRing->setEnabled( true );
mActionAddIsland->setEnabled( true );
mActionSplitFeatures->setEnabled( true );
+ mActionSimplifyFeature->setEnabled( true );
+ mActionDeleteHole->setEnabled( true );
+ mActionDeletePart->setEnabled( true );
}
else
{
@@ -5275,6 +5353,9 @@
mActionAddRing->setEnabled( false );
mActionAddIsland->setEnabled( false );
mActionSplitFeatures->setEnabled( false );
+ mActionSimplifyFeature->setEnabled( false );
+ mActionDeleteHole->setEnabled( false );
+ mActionDeletePart->setEnabled( false );
}
mActionCapturePoint->setEnabled( false );
mActionCaptureLine->setEnabled( false );
Modified: trunk/qgis/src/app/qgisapp.h
===================================================================
--- trunk/qgis/src/app/qgisapp.h 2009-05-02 14:27:25 UTC (rev 10699)
+++ trunk/qgis/src/app/qgisapp.h 2009-05-02 15:37:35 UTC (rev 10700)
@@ -42,6 +42,8 @@
class QgsClipboard;
class QgsComposer;
class QgsHelpViewer;
+class QgsFeature;
+
class QgsLegend;
class QgsMapCanvas;
class QgsMapLayer;
@@ -63,7 +65,6 @@
#include "qgsconfig.h"
#include "qgspoint.h"
-
/*! \class QgisApp
* \brief Main window for the Qgis application
*/
@@ -221,6 +222,9 @@
QAction *actionMoveVertex() { return mActionMoveVertex; }
QAction *actionAddRing() { return mActionAddRing; }
QAction *actionAddIsland() { return mActionAddIsland; }
+ QAction *actionSimplifyFeature() { return mActionSimplifyFeature; }
+ QAction *actionDeleteHole() { return mActionDeleteHole; }
+ QAction *actionDeletePart() { return mActionDeletePart; }
QAction *actionEditSeparator2() { return mActionEditSeparator2; }
QAction *actionPan() { return mActionPan; }
@@ -318,6 +322,7 @@
QToolBar *layerToolBar() { return mLayerToolBar; }
QToolBar *mapNavToolToolBar() { return mMapNavToolBar; }
QToolBar *digitizeToolBar() { return mDigitizeToolBar; }
+ QToolBar *advancedDigitizeToolBar() { return mAdvancedDigitizeToolBar; }
QToolBar *attributesToolBar() { return mAttributesToolBar; }
QToolBar *pluginToolBar() { return mPluginToolBar; }
QToolBar *helpToolBar() { return mHelpToolBar; }
@@ -495,6 +500,12 @@
void addRing();
//! activates the add island tool
void addIsland();
+ //! simplifies feature
+ void simplifyFeature();
+ //! deletes hole in polygon
+ void deleteHole();
+ //! deletes part of polygon
+ void deletePart();
//! activates the selection tool
void select();
@@ -666,6 +677,7 @@
QToolBar *mLayerToolBar;
QToolBar *mMapNavToolBar;
QToolBar *mDigitizeToolBar;
+ QToolBar *mAdvancedDigitizeToolBar;
QToolBar *mAttributesToolBar;
QToolBar *mPluginToolBar;
QToolBar *mHelpToolBar;
@@ -701,6 +713,10 @@
QAction *mActionAddRing;
QAction *mActionAddIsland;
QAction *mActionEditSeparator2;
+ QAction *mActionSimplifyFeature;
+ QAction *mActionDeleteHole;
+ QAction *mActionDeletePart;
+ QAction *mActionEditSeparator3;
QAction *mActionPan;
QAction *mActionZoomIn;
@@ -816,6 +832,9 @@
QgsMapTool* mVertexDelete;
QgsMapTool* mAddRing;
QgsMapTool* mAddIsland;
+ QgsMapTool* mSimplifyFeature;
+ QgsMapTool* mDeleteHole;
+ QgsMapTool* mDeletePart;
} mMapTools;
QgsMapTool *mNonEditMapTool;
@@ -921,6 +940,7 @@
QgsPythonUtils* mPythonUtils;
static QgisApp *smInstance;
+
};
#endif
Added: trunk/qgis/src/app/qgsmaptooldeletehole.cpp
===================================================================
--- trunk/qgis/src/app/qgsmaptooldeletehole.cpp (rev 0)
+++ trunk/qgis/src/app/qgsmaptooldeletehole.cpp 2009-05-02 15:37:35 UTC (rev 10700)
@@ -0,0 +1,161 @@
+/***************************************************************************
+ qgsmaptooldeletehole.h - delete a hole from polygon
+ ---------------------
+ begin : April 2009
+ copyright : (C) 2009 by Richard Kostecky
+ email : csf dot kostej at mail dot com
+ ***************************************************************************
+ * *
+ * 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 "qgsmaptooldeletehole.h"
+
+#include "qgsmapcanvas.h"
+#include "qgsvertexmarker.h"
+#include "qgsvectorlayer.h"
+
+#include <QMouseEvent>
+#include <QMessageBox>
+
+QgsMapToolDeleteHole::QgsMapToolDeleteHole( QgsMapCanvas* canvas )
+ : QgsMapToolVertexEdit( canvas ), mCross( 0 )
+{
+}
+
+QgsMapToolDeleteHole::~QgsMapToolDeleteHole()
+{
+ delete mCross;
+}
+
+void QgsMapToolDeleteHole::canvasMoveEvent( QMouseEvent * e )
+{
+ //nothing to do
+}
+
+void QgsMapToolDeleteHole::canvasPressEvent( QMouseEvent * e )
+{
+ delete mCross;
+ mCross = 0;
+
+ mRecentSnappingResults.clear();
+ //do snap -> new recent snapping results
+ if ( mSnapper.snapToCurrentLayer( e->pos(), mRecentSnappingResults, QgsSnapper::SnapToVertex ) != 0 )
+ {
+ //error
+ }
+
+ if ( mRecentSnappingResults.size() > 0 )
+ {
+ QgsPoint markerPoint = mRecentSnappingResults.begin()->snappedVertex;
+
+ //show vertex marker
+ mCross = new QgsVertexMarker( mCanvas );
+ mCross->setIconType( QgsVertexMarker::ICON_X );
+ mCross->setCenter( markerPoint );
+ }
+ else
+ {
+ displaySnapToleranceWarning();
+ }
+}
+
+void QgsMapToolDeleteHole::canvasReleaseEvent( QMouseEvent * e )
+{
+ delete mCross;
+ mCross = 0;
+
+ QgsMapLayer* currentLayer = mCanvas->currentLayer();
+ if ( !currentLayer )
+ return;
+
+ QgsVectorLayer* vlayer = dynamic_cast<QgsVectorLayer*>( currentLayer );
+ if ( !vlayer )
+ return;
+
+
+ if ( mRecentSnappingResults.size() > 0 )
+ {
+ QList<QgsSnappingResult>::iterator sr_it = mRecentSnappingResults.begin();
+ for ( ; sr_it != mRecentSnappingResults.end(); ++sr_it )
+ {
+ deleteHole( sr_it->snappedAtGeometry, sr_it->snappedVertexNr, vlayer);
+ }
+ }
+}
+
+
+void QgsMapToolDeleteHole::deleteHole( int fId, int beforeVertexNr, QgsVectorLayer* vlayer)
+{
+ QgsFeature f;
+ vlayer->featureAtId( fId, f );
+
+ QgsGeometry* g = f.geometry();
+ QGis::WkbType wkbtype = g->wkbType();
+ int ringNum, partNum = 0;
+
+ if (wkbtype == QGis::WKBPolygon || wkbtype == QGis::WKBPolygon25D)
+ {
+ ringNum = ringNumInPolygon( g, beforeVertexNr );
+ }
+ else if (wkbtype == QGis::WKBMultiPolygon || wkbtype == QGis::WKBMultiPolygon25D)
+ {
+ ringNum = ringNumInMultiPolygon( g, beforeVertexNr, partNum );
+ }
+ else
+ return;
+
+ if (g->deleteHole( ringNum, partNum ))
+ {
+ vlayer->deleteFeature( fId );
+ vlayer->addFeature(f);
+ mCanvas->refresh();
+ }
+
+}
+
+int QgsMapToolDeleteHole::ringNumInPolygon( QgsGeometry* g, int vertexNr )
+{
+ QgsPolygon polygon = g->asPolygon();
+ for (int ring = 0; ring < polygon.count(); ring++)
+ {
+ if (vertexNr < polygon[ring].count())
+ return ring;
+
+ vertexNr -= polygon[ring].count();
+ }
+ return -1;
+}
+
+int QgsMapToolDeleteHole::ringNumInMultiPolygon( QgsGeometry* g, int vertexNr, int& partNum )
+{
+ QgsMultiPolygon mpolygon = g->asMultiPolygon();
+ for (int part = 0; part < mpolygon.count(); part++)
+ {
+ const QgsPolygon& polygon = mpolygon[part];
+ for (int ring = 0; ring < polygon.count(); ring++)
+ {
+ if (vertexNr < polygon[ring].count())
+ {
+ partNum = part;
+ return ring;
+ }
+
+ vertexNr -= polygon[ring].count();
+ }
+ }
+ return -1;
+}
+
+
+void QgsMapToolDeleteHole::deactivate()
+{
+ delete mCross;
+ mCross = 0;
+
+ QgsMapTool::deactivate();
+}
Added: trunk/qgis/src/app/qgsmaptooldeletehole.h
===================================================================
--- trunk/qgis/src/app/qgsmaptooldeletehole.h (rev 0)
+++ trunk/qgis/src/app/qgsmaptooldeletehole.h 2009-05-02 15:37:35 UTC (rev 10700)
@@ -0,0 +1,53 @@
+/***************************************************************************
+ qgsmaptooldeletehole.h - delete a hole from polygon
+ ---------------------
+ begin : April 2009
+ copyright : (C) 2009 by Richard Kostecky
+ email : csf dot kostej at mail dot com
+ ***************************************************************************
+ * *
+ * 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 QGSMAPTOOLDELETEHOLE_H
+#define QGSMAPTOOLDELETEHOLE_H
+
+#include "qgsmaptoolvertexedit.h"
+#include <QUndoCommand>
+
+class QgsVertexMarker;
+/**Map tool to delete vertices from line/polygon features*/
+
+class QgsMapToolDeleteHole: public QgsMapToolVertexEdit
+{
+ public:
+ QgsMapToolDeleteHole( QgsMapCanvas* canvas );
+ virtual ~QgsMapToolDeleteHole();
+
+ void canvasMoveEvent( QMouseEvent * e );
+
+ void canvasPressEvent( QMouseEvent * e );
+
+ void canvasReleaseEvent( QMouseEvent * e );
+
+ //! called when map tool is being deactivated
+ void deactivate();
+
+ private:
+ QgsVertexMarker* mCross;
+
+ //! delete hole from the geometry
+ void deleteHole( int fId, int beforeVertexNr, QgsVectorLayer* vlayer);
+
+ //! return ring number in polygon
+ int ringNumInPolygon( QgsGeometry* g, int vertexNr );
+
+ //! return ring number in multipolygon and set parNum to index of the part
+ int ringNumInMultiPolygon( QgsGeometry* g, int vertexNr, int& partNum );
+};
+
+#endif
Added: trunk/qgis/src/app/qgsmaptooldeletepart.cpp
===================================================================
--- trunk/qgis/src/app/qgsmaptooldeletepart.cpp (rev 0)
+++ trunk/qgis/src/app/qgsmaptooldeletepart.cpp 2009-05-02 15:37:35 UTC (rev 10700)
@@ -0,0 +1,178 @@
+/***************************************************************************
+ qgsmaptooldeletepart.cpp - delete a part from multipart geometry
+ ---------------------
+ begin : April 2009
+ copyright : (C) 2009 by Richard Kostecky
+ email : csf dot kostej at mail dot com
+ ***************************************************************************
+ * *
+ * 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 "qgsmaptooldeletepart.h"
+
+#include "qgsmapcanvas.h"
+#include "qgsvertexmarker.h"
+#include "qgsvectorlayer.h"
+
+#include <QMouseEvent>
+#include <QMessageBox>
+
+QgsMapToolDeletePart::QgsMapToolDeletePart( QgsMapCanvas* canvas )
+ : QgsMapToolVertexEdit( canvas ), mCross( 0 )
+{
+}
+
+QgsMapToolDeletePart::~QgsMapToolDeletePart()
+{
+ delete mCross;
+}
+
+void QgsMapToolDeletePart::canvasMoveEvent( QMouseEvent * e )
+{
+ //nothing to do
+}
+
+void QgsMapToolDeletePart::canvasPressEvent( QMouseEvent * e )
+{
+ delete mCross;
+ mCross = 0;
+
+ mRecentSnappingResults.clear();
+ //do snap -> new recent snapping results
+ if ( mSnapper.snapToCurrentLayer( e->pos(), mRecentSnappingResults, QgsSnapper::SnapToVertex ) != 0 )
+ {
+ //error
+ }
+
+ if ( mRecentSnappingResults.size() > 0 )
+ {
+ QgsPoint markerPoint = mRecentSnappingResults.begin()->snappedVertex;
+
+ //show vertex marker
+ mCross = new QgsVertexMarker( mCanvas );
+ mCross->setIconType( QgsVertexMarker::ICON_X );
+ mCross->setCenter( markerPoint );
+ }
+ else
+ {
+ displaySnapToleranceWarning();
+ }
+}
+
+void QgsMapToolDeletePart::canvasReleaseEvent( QMouseEvent * e )
+{
+ delete mCross;
+ mCross = 0;
+
+ QgsMapLayer* currentLayer = mCanvas->currentLayer();
+ if ( !currentLayer )
+ return;
+
+ QgsVectorLayer* vlayer = dynamic_cast<QgsVectorLayer*>( currentLayer );
+ if ( !vlayer )
+ return;
+
+ if ( mRecentSnappingResults.size() > 0 )
+ {
+ QList<QgsSnappingResult>::iterator sr_it = mRecentSnappingResults.begin();
+ for ( ; sr_it != mRecentSnappingResults.end(); ++sr_it )
+ {
+ deletePart( sr_it->snappedAtGeometry, sr_it->snappedVertexNr, vlayer);
+ }
+ }
+
+}
+
+
+void QgsMapToolDeletePart::deletePart( int fId, int beforeVertexNr, QgsVectorLayer* vlayer)
+{
+ QgsFeature f;
+ vlayer->featureAtId( fId, f );
+
+ // find out the part number
+ QgsGeometry* g = f.geometry();
+ if ( !g->isMultipart() )
+ {
+ QMessageBox::information(mCanvas, tr("Delete part"), tr("This isn't a multipart geometry."));
+ return;
+ }
+
+ int partNum = partNumberOfVertex( g, beforeVertexNr );
+
+ if (g->deletePart( partNum ))
+ {
+ vlayer->deleteFeature( fId );
+ vlayer->addFeature(f);
+ mCanvas->refresh();
+ }
+ else
+ {
+ QMessageBox::information(mCanvas, tr("Delete part"), tr("Couldn't remove the selected part."));
+ }
+
+}
+
+int QgsMapToolDeletePart::partNumberOfVertex( QgsGeometry* g, int beforeVertexNr )
+{
+ int part;
+
+ switch ( g->wkbType() )
+ {
+ case QGis::WKBMultiPoint25D:
+ case QGis::WKBMultiPoint:
+ if ( beforeVertexNr < g->asMultiPoint().count() )
+ return beforeVertexNr;
+ else
+ return -1;
+
+ case QGis::WKBMultiLineString25D:
+ case QGis::WKBMultiLineString:
+ {
+ QgsMultiPolyline mline = g->asMultiPolyline();
+ for (part = 0; part < mline.count(); part++)
+ {
+ if (beforeVertexNr < mline[part].count())
+ return part;
+
+ beforeVertexNr -= mline[part].count();
+ }
+ return -1; // not found
+ }
+
+ case QGis::WKBMultiPolygon25D:
+ case QGis::WKBMultiPolygon:
+ {
+ QgsMultiPolygon mpolygon = g->asMultiPolygon();
+ for (part = 0; part < mpolygon.count(); part++) // go through the polygons
+ {
+ const QgsPolygon& polygon = mpolygon[part];
+ for (int ring = 0; ring < polygon.count(); ring++) // go through the rings
+ {
+ if (beforeVertexNr < polygon[ring].count())
+ return part;
+
+ beforeVertexNr -= polygon[ring].count();
+ }
+ }
+ return -1; // not found
+ }
+
+ default:
+ return -1;
+ }
+}
+
+
+void QgsMapToolDeletePart::deactivate()
+{
+ delete mCross;
+ mCross = 0;
+
+ QgsMapTool::deactivate();
+}
+
Added: trunk/qgis/src/app/qgsmaptooldeletepart.h
===================================================================
--- trunk/qgis/src/app/qgsmaptooldeletepart.h (rev 0)
+++ trunk/qgis/src/app/qgsmaptooldeletepart.h 2009-05-02 15:37:35 UTC (rev 10700)
@@ -0,0 +1,50 @@
+/***************************************************************************
+ qgsmaptooldeletepart.h - delete a part from multipart geometry
+ ---------------------
+ begin : April 2009
+ copyright : (C) 2009 by Richard Kostecky
+ email : csf dot kostej at mail dot com
+ ***************************************************************************
+ * *
+ * 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 QGSMAPTOOLDELETEPART_H
+#define QGSMAPTOOLDELETEPART_H
+
+#include "qgsmaptoolvertexedit.h"
+
+class QgsVertexMarker;
+
+/**Map tool to delete vertices from line/polygon features*/
+class QgsMapToolDeletePart: public QgsMapToolVertexEdit
+{
+ public:
+ QgsMapToolDeletePart( QgsMapCanvas* canvas );
+ virtual ~QgsMapToolDeletePart();
+
+ void canvasMoveEvent( QMouseEvent * e );
+
+ void canvasPressEvent( QMouseEvent * e );
+
+ void canvasReleaseEvent( QMouseEvent * e );
+
+ //! called when map tool is being deactivated
+ void deactivate();
+
+ private:
+ QgsVertexMarker* mCross;
+
+ //! delete part of a geometry
+ void deletePart( int fId, int beforeVertexNr, QgsVectorLayer* vlayer);
+
+ //! find out part number of geometry given the snapped vertex number
+ int partNumberOfVertex( QgsGeometry* g, int beforeVertexNr );
+
+};
+
+#endif
Added: trunk/qgis/src/app/qgsmaptoolsimplify.cpp
===================================================================
--- trunk/qgis/src/app/qgsmaptoolsimplify.cpp (rev 0)
+++ trunk/qgis/src/app/qgsmaptoolsimplify.cpp 2009-05-02 15:37:35 UTC (rev 10700)
@@ -0,0 +1,381 @@
+/***************************************************************************
+ qgsmaptoolsimplify.cpp - simplify vector layer features
+ ---------------------
+ begin : April 2009
+ copyright : (C) 2009 by Richard Kostecky
+ email : csf dot kostej at mail dot com
+ ***************************************************************************
+ * *
+ * 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 "qgsmaptoolsimplify.h"
+
+#include "qgsgeometry.h"
+#include "qgsmapcanvas.h"
+#include "qgsrubberband.h"
+#include "qgsvectorlayer.h"
+#include "qgstolerance.h"
+
+#include <QMouseEvent>
+
+#include <math.h>
+
+QgsSimplifyDialog::QgsSimplifyDialog(QWidget* parent)
+ : QDialog( parent )
+{
+ setupUi(this);
+ connect( horizontalSlider, SIGNAL( valueChanged( int ) ),
+ this, SLOT( valueChanged( int ) ) );
+ connect( okButton, SIGNAL(clicked()),
+ this, SLOT(simplify()));
+
+}
+
+void QgsSimplifyDialog::valueChanged(int value)
+{
+ emit toleranceChanged(value);
+}
+
+void QgsSimplifyDialog::simplify()
+{
+ emit storeSimplified();
+}
+
+void QgsSimplifyDialog::setRange(int minValue, int maxValue)
+{
+ horizontalSlider->setMinimum(minValue);
+ horizontalSlider->setMaximum(maxValue);
+
+ // let's have 20 page steps
+ horizontalSlider->setPageStep( (maxValue - minValue) / 20 );
+}
+
+
+QgsMapToolSimplify::QgsMapToolSimplify( QgsMapCanvas* canvas )
+ : QgsMapToolEdit( canvas), mRubberBand( 0 )
+{
+ mSimplifyDialog = new QgsSimplifyDialog( canvas->topLevelWidget() );
+ connect( mSimplifyDialog, SIGNAL( toleranceChanged( int ) ),
+ this, SLOT( toleranceChanged( int ) ) );
+ connect( mSimplifyDialog, SIGNAL( storeSimplified() ),
+ this, SLOT(storeSimplified()));
+ connect( mSimplifyDialog, SIGNAL(finished(int)),
+ this, SLOT(removeRubberBand()) );
+}
+
+QgsMapToolSimplify::~QgsMapToolSimplify()
+{
+ removeRubberBand();
+ delete mSimplifyDialog;
+}
+
+
+void QgsMapToolSimplify::toleranceChanged(int tolerance)
+{
+ mTolerance = double(tolerance)/toleranceDivider;
+
+ // create a copy of selected feature and do the simplification
+ QgsFeature f = mSelectedFeature;
+ QgsSimplifyFeature::simplifyLine(f, mTolerance);
+ mRubberBand->setToGeometry(f.geometry(), false);
+}
+
+
+void QgsMapToolSimplify::storeSimplified()
+{
+ QgsVectorLayer * vlayer = currentVectorLayer();
+ QgsSimplifyFeature::simplifyLine(mSelectedFeature, mTolerance);
+ // TODO(md): change geometry of feature instead of delete+add
+ vlayer->deleteFeature( mSelectedFeature.id() );
+ vlayer->addFeature(mSelectedFeature);
+
+ mCanvas->refresh();
+}
+
+int QgsMapToolSimplify::calculateDivider(double num)
+{
+ double tmp = num;
+ int i = 1;
+ while (tmp < 1)
+ {
+ tmp = tmp*10;
+ i = i *10;
+ }
+ return i;
+}
+
+void QgsMapToolSimplify::calculateSliderBoudaries()
+{
+ double minTolerance, maxTolerance;
+
+ double tol = 0.0000001;
+ bool found = false;
+ bool isLine = mSelectedFeature.geometry()->type() == QGis::Line;
+ QVector<QgsPoint> pts = getPointList(mSelectedFeature);
+ int size = pts.size();
+ if (size == 0 || (isLine && size < 2) || (!isLine && size < 3) )
+ {
+ return;
+ }
+
+ // calculate min
+ while (!found)
+ {
+ if (QgsSimplifyFeature::simplifyPoints(pts, tol).size() < size)
+ {
+ found = true;
+ minTolerance = tol/2;
+ } else {
+ tol = tol * 2;
+ }
+ }
+
+ found = false;
+ int requiredCnt = (isLine ? 2 : 3);
+ // calculate max
+ while (!found)
+ {
+ if (QgsSimplifyFeature::simplifyPoints(pts, tol).size() < requiredCnt + 1)
+ {
+//TODO: fix for polygon
+ found = true;
+ maxTolerance = tol;
+ } else {
+ tol = tol * 2;
+ }
+ }
+ toleranceDivider = calculateDivider(minTolerance);
+ // set min and max
+ mSimplifyDialog->setRange( int(minTolerance * toleranceDivider),
+ int(maxTolerance * toleranceDivider) );
+}
+
+
+void QgsMapToolSimplify::canvasPressEvent( QMouseEvent * e )
+{
+ QgsVectorLayer * vlayer = currentVectorLayer();
+ QgsPoint layerCoords = mCanvas->getCoordinateTransform()->toMapPoint( e->pos().x(), e->pos().y() );
+
+ double r = QgsTolerance::vertexSearchRadius(vlayer, mCanvas->mapRenderer());
+ QgsRectangle selectRect = QgsRectangle( layerCoords.x() - r, layerCoords.y() - r,
+ layerCoords.x() + r, layerCoords.y() + r);
+ vlayer->select( QgsAttributeList(), selectRect, true );
+
+ QgsGeometry* geometry = QgsGeometry::fromPoint( layerCoords );
+ double minDistance = 10000000;
+ double currentDistance;
+ QgsFeature f;
+
+ mSelectedFeature.setValid(FALSE);
+
+ while (vlayer->nextFeature(f))
+ {
+ currentDistance = geometry->distance( *(f.geometry()) );
+ if ( currentDistance < minDistance )
+ {
+ minDistance = currentDistance;
+ mSelectedFeature = f;
+ }
+ }
+
+ // delete previous rubberband (if any)
+ removeRubberBand();
+
+ if (mSelectedFeature.isValid())
+ {
+ mRubberBand = new QgsRubberBand(mCanvas);
+ mRubberBand->setToGeometry(mSelectedFeature.geometry(), false);
+ mRubberBand->setColor(Qt::red);
+ mRubberBand->setWidth(2);
+ mRubberBand->show();
+ //calculate boudaries for slidebar
+ calculateSliderBoudaries();
+
+ // show dialog as a non-modal window
+ mSimplifyDialog->show();
+ }
+}
+
+void QgsMapToolSimplify::removeRubberBand()
+{
+ delete mRubberBand;
+ mRubberBand = 0;
+}
+
+void QgsMapToolSimplify::deactivate()
+{
+ if (mSimplifyDialog->isVisible())
+ mSimplifyDialog->close();
+ removeRubberBand();
+ QgsMapTool::deactivate();
+}
+
+
+QVector<QgsPoint> QgsMapToolSimplify::getPointList(QgsFeature& f)
+{
+ QgsGeometry* line = f.geometry();
+ if ((line->type() != QGis::Line && line->type() != QGis::Polygon ) || line->isMultipart())
+ {
+ return QVector<QgsPoint>();
+ }
+ if ((line->type() == QGis::Line))
+ {
+ return line->asPolyline();
+ }
+ else
+ {
+ if (line->asPolygon().size() > 1)
+ {
+ return QVector<QgsPoint>();
+ }
+ return line->asPolygon()[0];
+ }
+
+}
+
+
+
+
+
+bool QgsSimplifyFeature::simplifyLine(QgsFeature& lineFeature, double tolerance)
+{
+ QgsGeometry* line = lineFeature.geometry();
+ if (line->type() != QGis::Line)
+ {
+ return FALSE;
+ }
+
+ QVector<QgsPoint> resultPoints = simplifyPoints(line->asPolyline(), tolerance);
+ lineFeature.setGeometry( QgsGeometry::fromPolyline( resultPoints ) );
+ return TRUE;
+}
+
+
+//TODO: change to correct structure after
+bool QgsSimplifyFeature::simplifyPartOfLine(QgsFeature& lineFeature, int fromVertexNr, int toVertexNr, double tolerance)
+{
+ QgsGeometry* line = lineFeature.geometry();
+ if (line->type() != QGis::Line)
+ {
+ return FALSE;
+ }
+
+ QVector<QgsPoint> resultPoints = simplifyPoints(line->asPolyline(), tolerance);
+ lineFeature.setGeometry( QgsGeometry::fromPolyline( resultPoints ) );
+ return TRUE;
+}
+
+
+
+QVector<QgsPoint> QgsSimplifyFeature::simplifyPoints (const QVector<QgsPoint>& pts, double tolerance)
+{
+ // Douglas-Peucker simplification algorithm
+
+ int anchor = 0;
+ int floater = pts.size() - 1;
+
+ QList<StackEntry> stack;
+ StackEntry temporary;
+ StackEntry entry = {anchor, floater};
+ stack.append(entry);
+
+ QSet<int> keep;
+ double anchorX;
+ double anchorY;
+ double seg_len;
+ double max_dist;
+ int farthest;
+ double dist_to_seg;
+ double vecX;
+ double vecY;
+
+ while (!stack.empty())
+ {
+ temporary = stack.takeLast();
+ anchor = temporary.anchor;
+ floater = temporary.floater;
+ // initialize line segment
+ if (pts[floater] != pts[anchor])
+ {
+ anchorX = pts[floater].x() - pts[anchor].x();
+ anchorY = pts[floater].y() - pts[anchor].y();
+ seg_len = sqrt(anchorX * anchorX + anchorY * anchorY);
+ // get the unit vector
+ anchorX /= seg_len;
+ anchorY /= seg_len;
+ }
+ else
+ {
+ anchorX = anchorY = seg_len = 0.0;
+ }
+ // inner loop:
+ max_dist = 0.0;
+ farthest = anchor + 1;
+ for (int i = anchor + 1; i < floater; i++)
+ {
+ dist_to_seg = 0.0;
+ // compare to anchor
+ vecX = pts[i].x() - pts[anchor].x();
+ vecY = pts[i].y() - pts[anchor].y();
+ seg_len = sqrt( vecX * vecX + vecY * vecY );
+ // dot product:
+ double proj = vecX * anchorX + vecY * anchorY;
+ if (proj < 0.0)
+ {
+ dist_to_seg = seg_len;
+ }
+ else
+ {
+ // compare to floater
+ vecX = pts[i].x() - pts[floater].x();
+ vecY = pts[i].y() - pts[floater].y();
+ seg_len = sqrt( vecX * vecX + vecY *vecY );
+ // dot product:
+ proj = vecX * (-anchorX) + vecY * (-anchorY);
+ if (proj < 0.0)
+ {
+ dist_to_seg = seg_len;
+ }
+ else
+ { // calculate perpendicular distance to line (pythagorean theorem):
+ dist_to_seg = sqrt(fabs(seg_len * seg_len - proj * proj));
+ }
+ if (max_dist < dist_to_seg)
+ {
+ max_dist = dist_to_seg;
+ farthest = i;
+ }
+ }
+ }
+ if (max_dist <= tolerance)
+ { // # use line segment
+ keep.insert(anchor);
+ keep.insert(floater);
+ }
+ else
+ {
+ StackEntry s = {anchor, farthest};
+ stack.append(s);
+
+ StackEntry r = {farthest, floater};
+ stack.append(r);
+ }
+ }
+
+ QList<int> keep2 = keep.toList();
+ qSort(keep2);
+
+ QVector<QgsPoint> result;
+ int position;
+ while (!keep2.empty())
+ {
+ position = keep2.takeFirst();
+ result.append(pts[position]);
+ }
+ return result;
+}
Added: trunk/qgis/src/app/qgsmaptoolsimplify.h
===================================================================
--- trunk/qgis/src/app/qgsmaptoolsimplify.h (rev 0)
+++ trunk/qgis/src/app/qgsmaptoolsimplify.h 2009-05-02 15:37:35 UTC (rev 10700)
@@ -0,0 +1,111 @@
+/***************************************************************************
+ qgsmaptoolsimplify.h - simplify vector layer features
+ ---------------------
+ begin : April 2009
+ copyright : (C) 2009 by Richard Kostecky
+ email : csf dot kostej at mail dot com
+ ***************************************************************************
+ * *
+ * 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 QGSMAPTOOLSIMPLIFY_H
+#define QGSMAPTOOLSIMPLIFY_H
+
+#include "qgsmaptooledit.h"
+#include "ui_qgssimplifytolerancedialog.h"
+
+#include <QVector>
+#include "qgsfeature.h"
+
+class QgsRubberBand;
+
+
+class QgsSimplifyDialog : public QDialog, private Ui::SimplifyLineDialog
+{
+ Q_OBJECT
+
+public:
+ QgsSimplifyDialog( QWidget* parent = NULL );
+
+ void setRange(int minValue, int maxValue);
+
+signals:
+ void toleranceChanged( int tol );
+ void storeSimplified();
+
+private slots:
+ void valueChanged( int value );
+ void simplify();
+};
+
+
+/**Map tool to add vertices to line/polygon features*/
+class QgsMapToolSimplify: public QgsMapToolEdit
+{
+ Q_OBJECT
+
+public:
+ QgsMapToolSimplify( QgsMapCanvas* canvas );
+ virtual ~QgsMapToolSimplify();
+
+ void canvasPressEvent( QMouseEvent * e );
+
+ //! called when map tool is being deactivated
+ void deactivate();
+
+public slots:
+ void removeRubberBand();
+
+private:
+
+ int calculateDivider(double num);
+
+ void calculateSliderBoudaries();
+
+ QVector<QgsPoint> getPointList(QgsFeature& f);
+
+ // data
+
+ QgsSimplifyDialog* mSimplifyDialog;
+
+ QgsRubberBand* mRubberBand;
+
+ QgsFeature mSelectedFeature;
+
+ int toleranceDivider;
+
+ double mTolerance;
+
+private slots:
+ void toleranceChanged(int tolerance);
+ void storeSimplified();
+
+};
+
+/**
+ Implementation of Douglas-Peucker simplification algorithm.
+ */
+class QgsSimplifyFeature
+{
+ struct StackEntry {
+ int anchor;
+ int floater;
+ };
+
+public:
+ /** simplify line feature with specified tolerance. Returns TRUE on success */
+ static bool simplifyLine(QgsFeature &lineFeature, double tolerance);
+ /** simplify a part of line feature specified by range of vertices with given tolerance. Returns TRUE on success */
+ static bool simplifyPartOfLine(QgsFeature &lineFeature, int fromVertexNr, int toVertexNr, double tolerance);
+ /** simplify a line given by a vector of points and tolerance. Returns simplified vector of points */
+ static QVector<QgsPoint> simplifyPoints (const QVector<QgsPoint>& pts, double tolerance);
+
+
+};
+
+#endif
Modified: trunk/qgis/src/core/qgsgeometry.cpp
===================================================================
--- trunk/qgis/src/core/qgsgeometry.cpp 2009-05-02 14:27:25 UTC (rev 10699)
+++ trunk/qgis/src/core/qgsgeometry.cpp 2009-05-02 15:37:35 UTC (rev 10700)
@@ -5540,3 +5540,117 @@
return geomCollection;
}
+
+
+bool QgsGeometry::deleteHole( int ringNum, int partNum )
+{
+ if (ringNum <= 0 || partNum < 0)
+ return FALSE;
+
+ switch ( wkbType() )
+ {
+ case QGis::WKBPolygon25D:
+ case QGis::WKBPolygon:
+ {
+ if (partNum != 0)
+ return FALSE;
+
+ QgsPolygon polygon = asPolygon();
+ if ( ringNum >= polygon.count() )
+ return FALSE;
+
+ polygon.remove( ringNum );
+
+ QgsGeometry* g2 = QgsGeometry::fromPolygon( polygon );
+ *this = *g2;
+ delete g2;
+ return TRUE;
+ }
+
+ case QGis::WKBMultiPolygon25D:
+ case QGis::WKBMultiPolygon:
+ {
+ QgsMultiPolygon mpolygon = asMultiPolygon();
+
+ if (partNum >= mpolygon.count())
+ return FALSE;
+
+ if ( ringNum >= mpolygon[partNum].count() )
+ return FALSE;
+
+ mpolygon[partNum].remove( ringNum );
+
+ QgsGeometry* g2 = QgsGeometry::fromMultiPolygon( mpolygon );
+ *this = *g2;
+ delete g2;
+ return TRUE;
+ }
+
+ default:
+ return FALSE; // only makes sense with polygons and multipolygons
+ }
+}
+
+
+bool QgsGeometry::deletePart( int partNum )
+{
+ if (partNum < 0)
+ return FALSE;
+
+ switch ( wkbType() )
+ {
+ case QGis::WKBMultiPoint25D:
+ case QGis::WKBMultiPoint:
+ {
+ QgsMultiPoint mpoint = asMultiPoint();
+
+ if (partNum >= mpoint.size() || mpoint.size() == 1)
+ return FALSE;
+
+ mpoint.remove( partNum );
+
+ QgsGeometry* g2 = QgsGeometry::fromMultiPoint( mpoint );
+ *this = *g2;
+ delete g2;
+ break;
+ }
+
+ case QGis::WKBMultiLineString25D:
+ case QGis::WKBMultiLineString:
+ {
+ QgsMultiPolyline mline = asMultiPolyline();
+
+ if (partNum >= mline.size() || mline.size() == 1)
+ return FALSE;
+
+ mline.remove( partNum );
+
+ QgsGeometry* g2 = QgsGeometry::fromMultiPolyline( mline );
+ *this = *g2;
+ delete g2;
+ break;
+ }
+
+ case QGis::WKBMultiPolygon25D:
+ case QGis::WKBMultiPolygon:
+ {
+ QgsMultiPolygon mpolygon = asMultiPolygon();
+
+ if (partNum >= mpolygon.size() || mpolygon.size() == 1)
+ return FALSE;
+
+ mpolygon.remove( partNum );
+
+ QgsGeometry* g2 = QgsGeometry::fromMultiPolygon( mpolygon );
+ *this = *g2;
+ delete g2;
+ break;
+ }
+
+ default:
+ // single part geometries are ignored
+ return FALSE;
+ }
+
+ return TRUE;
+}
Modified: trunk/qgis/src/core/qgsgeometry.h
===================================================================
--- trunk/qgis/src/core/qgsgeometry.h 2009-05-02 14:27:25 UTC (rev 10699)
+++ trunk/qgis/src/core/qgsgeometry.h 2009-05-02 15:37:35 UTC (rev 10700)
@@ -332,6 +332,18 @@
@note added in version 1.1 */
QList<QgsGeometry*> asGeometryCollection();
+ /** delete a hole in polygon or multipolygon.
+ Ring 0 is outer ring and can't be deleted.
+ @return TRUE on success
+ @note added in version 1.2 */
+ bool deleteHole( int ringNum, int partNum = 0 );
+
+ /** delete part identified by the part number
+ @return TRUE on success
+ @note added in version 1.2 */
+ bool deletePart( int partNum );
+
+
private:
// Private variables
Added: trunk/qgis/src/ui/qgssimplifytolerancedialog.ui
===================================================================
--- trunk/qgis/src/ui/qgssimplifytolerancedialog.ui (rev 0)
+++ trunk/qgis/src/ui/qgssimplifytolerancedialog.ui 2009-05-02 15:37:35 UTC (rev 10700)
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SimplifyLineDialog</class>
+ <widget class="QDialog" name="SimplifyLineDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>431</width>
+ <height>54</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Simplify line tolerance</string>
+ </property>
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Set tolerance</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="horizontalSlider">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="okButton">
+ <property name="text">
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>okButton</sender>
+ <signal>clicked()</signal>
+ <receiver>SimplifyLineDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>390</x>
+ <y>24</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>236</x>
+ <y>30</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
More information about the QGIS-commit
mailing list