[QGIS Commit] r11211 - trunk/qgis/src/plugins/interpolation

svn_qgis at osgeo.org svn_qgis at osgeo.org
Thu Jul 30 07:30:33 EDT 2009


Author: mhugent
Date: 2009-07-30 07:30:33 -0400 (Thu, 30 Jul 2009)
New Revision: 11211

Modified:
   trunk/qgis/src/plugins/interpolation/DualEdgeTriangulation.cc
   trunk/qgis/src/plugins/interpolation/DualEdgeTriangulation.h
   trunk/qgis/src/plugins/interpolation/Triangulation.h
   trunk/qgis/src/plugins/interpolation/qgsidwinterpolator.cpp
   trunk/qgis/src/plugins/interpolation/qgsidwinterpolator.h
   trunk/qgis/src/plugins/interpolation/qgsidwinterpolatordialog.cpp
   trunk/qgis/src/plugins/interpolation/qgsinterpolationdialog.cpp
   trunk/qgis/src/plugins/interpolation/qgsinterpolationdialog.h
   trunk/qgis/src/plugins/interpolation/qgsinterpolationdialogbase.ui
   trunk/qgis/src/plugins/interpolation/qgsinterpolator.cpp
   trunk/qgis/src/plugins/interpolation/qgsinterpolator.h
   trunk/qgis/src/plugins/interpolation/qgsinterpolatordialog.cpp
   trunk/qgis/src/plugins/interpolation/qgsinterpolatordialog.h
   trunk/qgis/src/plugins/interpolation/qgstininterpolator.cpp
   trunk/qgis/src/plugins/interpolation/qgstininterpolator.h
   trunk/qgis/src/plugins/interpolation/qgstininterpolatordialog.cpp
Log:
FEATURE: possibility to add line layers as constrains for triangulation in interpolation plugin

Modified: trunk/qgis/src/plugins/interpolation/DualEdgeTriangulation.cc
===================================================================
--- trunk/qgis/src/plugins/interpolation/DualEdgeTriangulation.cc	2009-07-30 11:08:18 UTC (rev 11210)
+++ trunk/qgis/src/plugins/interpolation/DualEdgeTriangulation.cc	2009-07-30 11:30:33 UTC (rev 11211)
@@ -17,7 +17,9 @@
 
 #include "DualEdgeTriangulation.h"
 #include <map>
+#include "qgsgeometry.h"
 #include "qgslogger.h"
+#include "qgsvectorfilewriter.h"
 
 double leftOfTresh = 0.00000001;
 
@@ -75,7 +77,7 @@
     for ( i = 0;i < line->getSize();i++ )
     {
       line->goToNext();
-      actpoint = mDecorator->addPoint( line->getPoint() );
+      actpoint = /*mDecorator->*/addPoint( line->getPoint() );
       if ( actpoint != -100 )
       {
         i++;
@@ -85,20 +87,22 @@
 
     if ( actpoint == -100 )//no point of the line could be inserted
     {
+      delete line;
       return;
     }
 
     for ( ;i < line->getSize();i++ )
     {
       line->goToNext();
-      currentpoint = mDecorator->addPoint( line->getPoint() );
-      //if(currentpoint!=-100&&actpoint!=-100&&currentpoint!=actpoint)//-100 is the return value if the point could not be not inserted
-      //{
-      // insertForcedSegment(actpoint,currentpoint,breakline);
-      //}
+      currentpoint = /*mDecorator->*/addPoint( line->getPoint() );
+      if ( currentpoint != -100 && actpoint != -100 && currentpoint != actpoint )//-100 is the return value if the point could not be not inserted
+      {
+        insertForcedSegment( actpoint, currentpoint, breakline );
+      }
       actpoint = currentpoint;
     }
   }
+  delete line;
 }
 
 int DualEdgeTriangulation::addPoint( Point3D* p )
@@ -1178,7 +1182,6 @@
 
 }
 
-#if 0
 int DualEdgeTriangulation::insertForcedSegment( int p1, int p2, bool breakline )
 {
   if ( p1 == p2 )
@@ -1436,8 +1439,8 @@
   }
 
   //set the flags 'forced' and 'break' to false for every edge and dualedge of 'crossEdges'
-  QListIterator<int> iter;
-  for ( iter = crossedEdges.begin();iter != crossedEdges.end();++iter )
+  QList<int>::const_iterator iter;
+  for ( iter = crossedEdges.constBegin();iter != crossedEdges.constEnd();++iter )
   {
     mHalfEdge[( *( iter ) )]->setForced( false );
     mHalfEdge[( *( iter ) )]->setBreak( false );
@@ -1467,8 +1470,9 @@
 
   //finish the polygon on the left side
   int actpointl = p2;
-  QListIterator<int> leftiter;
-  leftiter = crossedEdges.fromLast();
+  QList<int>::const_iterator leftiter; //todo: is there a better way to set an iterator to the last list element?
+  leftiter = crossedEdges.constEnd();
+  --leftiter;
   while ( true )
   {
     int newpoint = mHalfEdge[mHalfEdge[mHalfEdge[mHalfEdge[( *leftiter )]->getDual()]->getNext()]->getNext()]->getPoint();
@@ -1479,7 +1483,7 @@
       int theedge = mHalfEdge[mHalfEdge[mHalfEdge[( *leftiter )]->getDual()]->getNext()]->getNext();
       leftPolygon.append( theedge );
     }
-    if ( leftiter == crossedEdges.begin() )
+    if ( leftiter == crossedEdges.constBegin() )
       {break;}
     --leftiter;
   }
@@ -1488,9 +1492,9 @@
   leftPolygon.append( mHalfEdge[crossedEdges.first()]->getNext() );
 
   //finish the polygon on the right side
-  QValueListIterator<int> rightiter;
+  QList<int>::const_iterator rightiter;
   int actpointr = p1;
-  for ( rightiter = crossedEdges.begin();rightiter != crossedEdges.end();++rightiter )
+  for ( rightiter = crossedEdges.constBegin();rightiter != crossedEdges.constEnd();++rightiter )
   {
     int newpoint = mHalfEdge[mHalfEdge[mHalfEdge[( *rightiter )]->getNext()]->getNext()]->getPoint();
     if ( newpoint != actpointr )
@@ -1509,7 +1513,8 @@
 
   //set the necessary nexts of leftPolygon(exept the first)
   int actedgel = leftPolygon[1];
-  for ( leftiter = leftPolygon.at( 2 );leftiter != leftPolygon.end();++leftiter )
+  leftiter = leftPolygon.constBegin(); leftiter += 2;
+  for ( ;leftiter != leftPolygon.constEnd();++leftiter )
   {
     mHalfEdge[actedgel]->setNext(( *leftiter ) );
     actedgel = ( *leftiter );
@@ -1517,7 +1522,8 @@
 
   //set all the necessary nexts of rightPolygon
   int actedger = rightPolygon[1];
-  for ( rightiter = rightPolygon.at( 2 );rightiter != rightPolygon.end();++rightiter )
+  rightiter = rightPolygon.constBegin(); rightiter += 2;
+  for ( ;rightiter != rightPolygon.constEnd();++rightiter )
   {
     mHalfEdge[actedger]->setNext(( *rightiter ) );
     actedger = ( *( rightiter ) );
@@ -1532,8 +1538,6 @@
   mHalfEdge[rightPolygon.first()]->setPoint( p1 );
   mHalfEdge[rightPolygon.last()]->setNext( dualfirstedge );
 
-
-
   triangulatePolygon( &leftPolygon, &freelist, firstedge );
   triangulatePolygon( &rightPolygon, &freelist, dualfirstedge );
 
@@ -1545,7 +1549,6 @@
 
   return leftPolygon.first();
 }
-#endif //0
 
 void DualEdgeTriangulation::setForcedCrossBehaviour( Triangulation::forcedCrossBehaviour b )
 {
@@ -2442,7 +2445,6 @@
   return true;
 }
 
-#if 0
 void DualEdgeTriangulation::triangulatePolygon( QList<int>* poly, QList<int>* free, int mainedge )
 {
   if ( poly && free )
@@ -2453,13 +2455,13 @@
     }
 
     //search for the edge pointing on the closest point(distedge) and for the next(nextdistedge)
-    QValueListIterator<int> iterator = ++( poly->begin() );//go to the second edge
+    QList<int>::const_iterator iterator = ++( poly->constBegin() );//go to the second edge
     double distance = MathUtils::distPointFromLine( mPointVector[mHalfEdge[( *iterator )]->getPoint()], mPointVector[mHalfEdge[mHalfEdge[mainedge]->getDual()]->getPoint()], mPointVector[mHalfEdge[mainedge]->getPoint()] );
     int distedge = ( *iterator );
     int nextdistedge = mHalfEdge[( *iterator )]->getNext();
     ++iterator;
 
-    while ( iterator != --( poly->end() ) )
+    while ( iterator != --( poly->constEnd() ) )
     {
       if ( MathUtils::distPointFromLine( mPointVector[mHalfEdge[( *iterator )]->getPoint()], mPointVector[mHalfEdge[mHalfEdge[mainedge]->getDual()]->getPoint()], mPointVector[mHalfEdge[mainedge]->getPoint()] ) < distance )
       {
@@ -2476,15 +2478,15 @@
       int insertb = mHalfEdge[inserta]->getDual();
       free->pop_front();
 
-      mHalfEdge[inserta]->setNext(( *( poly->at( 1 ) ) ) );
+      mHalfEdge[inserta]->setNext(( poly->at( 1 ) ) );
       mHalfEdge[inserta]->setPoint( mHalfEdge[mainedge]->getPoint() );
       mHalfEdge[insertb]->setNext( nextdistedge );
       mHalfEdge[insertb]->setPoint( mHalfEdge[distedge]->getPoint() );
       mHalfEdge[distedge]->setNext( inserta );
       mHalfEdge[mainedge]->setNext( insertb );
 
-      QValueList<int> polya;
-      for ( iterator = ( ++( poly->begin() ) );( *iterator ) != nextdistedge;++iterator )
+      QList<int> polya;
+      for ( iterator = ( ++( poly->constBegin() ) );( *iterator ) != nextdistedge;++iterator )
       {
         polya.append(( *iterator ) );
       }
@@ -2507,16 +2509,16 @@
       int insertb = mHalfEdge[inserta]->getDual();
       free->pop_front();
 
-      mHalfEdge[inserta]->setNext(( *( poly->at( 2 ) ) ) );
+      mHalfEdge[inserta]->setNext(( poly->at( 2 ) ) );
       mHalfEdge[inserta]->setPoint( mHalfEdge[distedge]->getPoint() );
       mHalfEdge[insertb]->setNext( mainedge );
       mHalfEdge[insertb]->setPoint( mHalfEdge[mHalfEdge[mainedge]->getDual()]->getPoint() );
       mHalfEdge[distedge]->setNext( insertb );
       mHalfEdge[( *( --poly->end() ) )]->setNext( inserta );
 
-      QValueList<int> polya;
-      iterator = poly->at( 2 );
-      while ( iterator != poly->end() )
+      QList<int> polya;
+      iterator = poly->constBegin(); iterator += 2;
+      while ( iterator != poly->constEnd() )
       {
         polya.append(( *iterator ) );
         ++iterator;
@@ -2536,7 +2538,7 @@
       int insertd = mHalfEdge[insertc]->getDual();
       free->pop_front();
 
-      mHalfEdge[inserta]->setNext(( *( poly->at( 1 ) ) ) );
+      mHalfEdge[inserta]->setNext(( poly->at( 1 ) ) );
       mHalfEdge[inserta]->setPoint( mHalfEdge[mainedge]->getPoint() );
       mHalfEdge[insertb]->setNext( insertd );
       mHalfEdge[insertb]->setPoint( mHalfEdge[distedge]->getPoint() );
@@ -2550,17 +2552,17 @@
       mHalfEdge[( *( --poly->end() ) )]->setNext( insertc );
 
       //build two new polygons for recursive triangulation
-      QValueList<int> polya;
-      QValueList<int> polyb;
+      QList<int> polya;
+      QList<int> polyb;
 
-      for ( iterator = ++( poly->begin() );( *iterator ) != nextdistedge;++iterator )
+      for ( iterator = ++( poly->constBegin() );( *iterator ) != nextdistedge;++iterator )
       {
         polya.append(( *iterator ) );
       }
       polya.prepend( inserta );
 
 
-      while ( iterator != poly->end() )
+      while ( iterator != poly->constEnd() )
       {
         polyb.append(( *iterator ) );
         ++iterator;
@@ -2578,7 +2580,6 @@
   }
 
 }
-#endif //0
 
 bool DualEdgeTriangulation::pointInside( double x, double y )
 {
@@ -3070,6 +3071,62 @@
   }
 }
 
+bool DualEdgeTriangulation::saveAsShapefile( const QString& fileName ) const
+{
+  QgsFieldMap fields;
+  fields.insert( 0, QgsField( "type", QVariant::String, "String" ) );
+  QgsVectorFileWriter writer( fileName, "Utf-8", fields, QGis::WKBLineString, 0 );
+  if ( writer.hasError() != QgsVectorFileWriter::NoError )
+  {
+    return false;
+  }
+
+  bool alreadyVisitedEdges[mHalfEdge.size()];
+
+  for ( int i = 0; i < mHalfEdge.size(); ++i )
+  {
+    alreadyVisitedEdges[i] = false;
+  }
+
+  for ( int i = 0; i < mHalfEdge.size(); ++i )
+  {
+    HalfEdge* currentEdge = mHalfEdge[i];
+    if ( currentEdge->getPoint() != -1 && mHalfEdge[currentEdge->getDual()]->getPoint() != -1 && !alreadyVisitedEdges[currentEdge->getDual()] )
+    {
+      QgsFeature edgeLineFeature;
+
+      //geometry
+      Point3D* p1 = mPointVector[currentEdge->getPoint()];
+      Point3D* p2 = mPointVector[mHalfEdge[currentEdge->getDual()]->getPoint()];
+      QgsPolyline lineGeom;
+      lineGeom.push_back( QgsPoint( p1->getX(), p1->getY() ) );
+      lineGeom.push_back( QgsPoint( p2->getX(), p2->getY() ) );
+      QgsGeometry* geom = QgsGeometry::fromPolyline( lineGeom );
+      edgeLineFeature.setGeometry( geom );
+
+      //attributes
+      QString attributeString;
+      if ( currentEdge->getForced() )
+      {
+        if ( currentEdge->getBreak() )
+        {
+          attributeString = "break line";
+        }
+        else
+        {
+          attributeString = "structure line";
+        }
+      }
+      edgeLineFeature.addAttribute( 0, attributeString );
+
+      writer.addFeature( edgeLineFeature );
+    }
+    alreadyVisitedEdges[i] = true;
+  }
+
+  return true;
+}
+
 double DualEdgeTriangulation::swapMinAngle( int edge ) const
 {
   Point3D* p1 = getPoint( mHalfEdge[edge]->getPoint() );

Modified: trunk/qgis/src/plugins/interpolation/DualEdgeTriangulation.h
===================================================================
--- trunk/qgis/src/plugins/interpolation/DualEdgeTriangulation.h	2009-07-30 11:08:18 UTC (rev 11210)
+++ trunk/qgis/src/plugins/interpolation/DualEdgeTriangulation.h	2009-07-30 11:30:33 UTC (rev 11211)
@@ -43,7 +43,7 @@
     DualEdgeTriangulation();
     DualEdgeTriangulation( int nop, Triangulation* decorator );
     virtual ~DualEdgeTriangulation();
-    /**Adds a line (e.g. a break-, structure- or an isoline) to the triangulation*/
+    /**Adds a line (e.g. a break-, structure- or an isoline) to the triangulation. The class takes ownership of the line object and its points*/
     void addLine( Line3D* line, bool breakline );
     /**Adds a point to the triangulation and returns the number of this point in case of success or -100 in case of failure*/
     int addPoint( Point3D* p );
@@ -104,6 +104,9 @@
     virtual bool swapEdge( double x, double y );
     /**Returns a value list with the numbers of the four points, which would be affected by an edge swap. This function is e.g. needed by NormVecDecorator to know the points, for which the normals have to be recalculated. The returned ValueList has to be deleted by the code which calls the method*/
     virtual QList<int>* getPointsAroundEdge( double x, double y );
+    /**Saves the triangulation as a (line) shapefile
+    @return true in case of success*/
+    virtual bool saveAsShapefile( const QString& fileName ) const;
 
   protected:
     /**X-coordinate of the upper right corner of the bounding box*/
@@ -137,7 +140,7 @@
     /**inserts an edge and makes sure, everything is ok with the storage of the edge. The number of the HalfEdge is returned*/
     unsigned int insertEdge( int dual, int next, int point, bool mbreak, bool forced );
     /**inserts a forced segment between the points with the numbers p1 and p2 into the triangulation and returns the number of a HalfEdge belonging to this forced edge or -100 in case of failure*/
-    //int insertForcedSegment(int p1, int p2, bool breakline);
+    int insertForcedSegment( int p1, int p2, bool breakline );
     /**Treshold for the leftOfTest to handle numerical instabilities*/
     //const static double leftOfTresh=0.00001;
     /**Security to prevent endless loops in 'baseEdgeOfTriangle'. It there are more iteration then this number, the point will not be inserted*/
@@ -165,7 +168,7 @@
     /**Returns true, if it is possible to swap an edge, otherwise false(concave quad or edge on (or outside) the convex hull)*/
     bool swapPossible( unsigned int edge );
     /**divides a polygon in a triangle and two polygons and calls itself recursively for these two polygons. 'poly' is a pointer to a list with the numbers of the edges of the polygon, 'free' is a pointer to a list of free halfedges, and 'mainedge' is the number of the edge, towards which the new triangle is inserted. Mainedge has to be the same as poly->begin(), otherwise the recursion does not work*/
-    //void triangulatePolygon(QList<int>* poly, QList<int>* free, int mainedge);
+    void triangulatePolygon( QList<int>* poly, QList<int>* free, int mainedge );
     /**Tests, if the bounding box of the halfedge with index i intersects the specified bounding box. The main purpose for this method is the drawing of the triangulation*/
     bool halfEdgeBBoxTest( int edge, double xlowleft, double ylowleft, double xupright, double yupright ) const;
     /**Calculates the minimum angle, which would be present, if the specified halfedge would be swapped*/

Modified: trunk/qgis/src/plugins/interpolation/Triangulation.h
===================================================================
--- trunk/qgis/src/plugins/interpolation/Triangulation.h	2009-07-30 11:08:18 UTC (rev 11210)
+++ trunk/qgis/src/plugins/interpolation/Triangulation.h	2009-07-30 11:30:33 UTC (rev 11211)
@@ -31,7 +31,7 @@
     /**Enumeration describing the behaviour, if two forced lines cross. SnappingType_VERTICE means, that the second inserted forced line is snapped to the closest vertice of the first inserted forced line. DELETE_FIRST means, that the status of the first inserted forced line is reset to that of a normal edge (so that the second inserted forced line remain and the first not*/
     enum forcedCrossBehaviour {SnappingType_VERTICE, DELETE_FIRST, INSERT_VERTICE};
     virtual ~Triangulation();
-    /**Adds a line (e.g. a break-, structure- or an isoline) to the triangulation*/
+    /**Adds a line (e.g. a break-, structure- or an isoline) to the triangulation. The class takes ownership of the line object and its points*/
     virtual void addLine( Line3D* line, bool breakline ) = 0;
     /**Adds a point to the triangulation*/
     virtual int addPoint( Point3D* p ) = 0;
@@ -88,6 +88,9 @@
     //virtual bool saveToTAFF(QString fileName) const=0;
     /**Swaps the edge which is closest to the point with x and y coordinates (if this is possible)*/
     virtual bool swapEdge( double x, double y ) = 0;
+    /**Saves the triangulation as a (line) shapefile
+    @return true in case of success*/
+    virtual bool saveAsShapefile( const QString& fileName ) const = 0;
 };
 
 inline Triangulation::~Triangulation()

Modified: trunk/qgis/src/plugins/interpolation/qgsidwinterpolator.cpp
===================================================================
--- trunk/qgis/src/plugins/interpolation/qgsidwinterpolator.cpp	2009-07-30 11:08:18 UTC (rev 11210)
+++ trunk/qgis/src/plugins/interpolation/qgsidwinterpolator.cpp	2009-07-30 11:30:33 UTC (rev 11211)
@@ -19,12 +19,12 @@
 #include <cmath>
 #include <limits>
 
-QgsIDWInterpolator::QgsIDWInterpolator( const QList<QgsVectorLayer*>& vlayers ): QgsInterpolator( vlayers ), mDistanceCoefficient( 2.0 )
+QgsIDWInterpolator::QgsIDWInterpolator( const QList<LayerData>& layerData ): QgsInterpolator( layerData ), mDistanceCoefficient( 2.0 )
 {
 
 }
 
-QgsIDWInterpolator::QgsIDWInterpolator(): QgsInterpolator( QList<QgsVectorLayer*>() ), mDistanceCoefficient( 2.0 )
+QgsIDWInterpolator::QgsIDWInterpolator(): QgsInterpolator( QList<LayerData>() ), mDistanceCoefficient( 2.0 )
 {
 
 }

Modified: trunk/qgis/src/plugins/interpolation/qgsidwinterpolator.h
===================================================================
--- trunk/qgis/src/plugins/interpolation/qgsidwinterpolator.h	2009-07-30 11:08:18 UTC (rev 11210)
+++ trunk/qgis/src/plugins/interpolation/qgsidwinterpolator.h	2009-07-30 11:30:33 UTC (rev 11211)
@@ -23,7 +23,7 @@
 class QgsIDWInterpolator: public QgsInterpolator
 {
   public:
-    QgsIDWInterpolator( const QList<QgsVectorLayer*>& vlayers );
+    QgsIDWInterpolator( const QList<LayerData>& layerData );
     ~QgsIDWInterpolator();
 
     /**Calculates interpolation value for map coordinates x, y

Modified: trunk/qgis/src/plugins/interpolation/qgsidwinterpolatordialog.cpp
===================================================================
--- trunk/qgis/src/plugins/interpolation/qgsidwinterpolatordialog.cpp	2009-07-30 11:08:18 UTC (rev 11210)
+++ trunk/qgis/src/plugins/interpolation/qgsidwinterpolatordialog.cpp	2009-07-30 11:30:33 UTC (rev 11211)
@@ -13,15 +13,7 @@
 
 QgsInterpolator* QgsIDWInterpolatorDialog::createInterpolator() const
 {
-  QList<QgsVectorLayer*> inputLayerList;
-
-  QList< QPair <QgsVectorLayer*, QgsInterpolator::InputType> >::const_iterator data_it = mInputData.constBegin();
-  for ( ; data_it != mInputData.constEnd(); ++data_it )
-  {
-    inputLayerList.push_back( data_it->first );
-  }
-
-  QgsIDWInterpolator* theInterpolator = new QgsIDWInterpolator( inputLayerList );
+  QgsIDWInterpolator* theInterpolator = new QgsIDWInterpolator( mInputData );
   theInterpolator->setDistanceCoefficient( mPSpinBox->value() );
   return theInterpolator;
 }

Modified: trunk/qgis/src/plugins/interpolation/qgsinterpolationdialog.cpp
===================================================================
--- trunk/qgis/src/plugins/interpolation/qgsinterpolationdialog.cpp	2009-07-30 11:08:18 UTC (rev 11210)
+++ trunk/qgis/src/plugins/interpolation/qgsinterpolationdialog.cpp	2009-07-30 11:30:33 UTC (rev 11211)
@@ -25,6 +25,7 @@
 #include "qgsmaplayerregistry.h"
 #include "qgsvectordataprovider.h"
 #include "qgsvectorlayer.h"
+#include <QComboBox>
 #include <QFileDialog>
 #include <QMessageBox>
 
@@ -67,32 +68,88 @@
     return;
   }
 
+  //todo: test if an input layer is there and warn the user if not
+
   //read file name
   QString fileName = mOutputFileLineEdit->text();
   QFileInfo theFileInfo( fileName );
-  if ( !theFileInfo.dir().exists() )
+  if ( fileName.isEmpty() || !theFileInfo.dir().exists() )
   {
-    QMessageBox::information( 0, "File name invalid", "Please enter a valid file name" );
+    QMessageBox::information( 0, tr( "Output file name invalid" ), tr( "Please enter a valid output file name" ) );
     return;
   }
 
-  //get Vectorlayer
-  QgsVectorLayer* theVectorLayer = getCurrentVectorLayer();
-  if ( !theVectorLayer )
+  int nLayers = mLayersTreeWidget->topLevelItemCount();
+  QList< QgsInterpolator::LayerData > inputLayerList;
+  QgsRectangle combinedLayerExtent;
+
+  for ( int i = 0; i < nLayers; ++i )
   {
-    return;
-  }
+    QString layerName = mLayersTreeWidget->topLevelItem( i )->text( 0 );
+    QgsVectorLayer* theVectorLayer = vectorLayerFromName( layerName );
+    if ( !theVectorLayer )
+    {
+      continue;
+    }
 
-  QgsVectorDataProvider* theProvider = theVectorLayer->dataProvider();
-  if ( !theProvider )
-  {
-    return;
+    QgsVectorDataProvider* theProvider = theVectorLayer->dataProvider();
+    if ( !theProvider )
+    {
+      continue;
+    }
+
+    //update extent
+    QgsRectangle currentLayerExtent = theVectorLayer->extent();
+    if ( combinedLayerExtent.isEmpty() )
+    {
+      combinedLayerExtent = currentLayerExtent;
+    }
+    else
+    {
+      combinedLayerExtent.combineExtentWith( &currentLayerExtent );
+    }
+
+    QgsInterpolator::LayerData currentLayerData;
+    currentLayerData.vectorLayer = theVectorLayer;
+
+    QString interpolationAttString = mLayersTreeWidget->topLevelItem( i )->text( 1 );
+    if ( interpolationAttString == "Z_COORD" )
+    {
+      currentLayerData.zCoordInterpolation = true;
+    }
+    else
+    {
+      currentLayerData.zCoordInterpolation = false;
+      int attributeIndex = theProvider->fieldNameIndex( interpolationAttString );
+      currentLayerData.interpolationAttribute = attributeIndex;
+    }
+
+    //type (point/structure line/ breakline)
+    QComboBox* itemCombo = dynamic_cast<QComboBox*>( mLayersTreeWidget->itemWidget( mLayersTreeWidget->topLevelItem( i ), 2 ) );
+    if ( itemCombo )
+    {
+      QString typeString = itemCombo->currentText();
+      if ( typeString == tr( "Break lines" ) )
+      {
+        currentLayerData.mInputType = QgsInterpolator::BREAK_LINES;
+      }
+      else if ( typeString == tr( "Structure lines" ) )
+      {
+        currentLayerData.mInputType = QgsInterpolator::STRUCTURE_LINES;
+      }
+      else //Points
+      {
+        currentLayerData.mInputType = QgsInterpolator::POINTS;
+      }
+    }
+    else
+    {
+      currentLayerData.mInputType == QgsInterpolator::POINTS;
+    }
+    inputLayerList.push_back( currentLayerData );
   }
 
-  QPair<QgsVectorLayer*, QgsInterpolator::InputType> layerPair( theVectorLayer, QgsInterpolator::POINTS );
-  QList< QPair <QgsVectorLayer*, QgsInterpolator::InputType> > layerInputList;
-  layerInputList.push_back( layerPair );
-  mInterpolatorDialog->setInputData( layerInputList );
+  mInterpolatorDialog->setInputData( inputLayerList );
   QgsInterpolator* theInterpolator = mInterpolatorDialog->createInterpolator();
 
   if ( !theInterpolator )
@@ -100,23 +157,15 @@
     return;
   }
 
-  if ( mUseZCoordCheckBox->checkState() == Qt::Checked )
-  {
-    theInterpolator->enableZCoordInterpolation();
-  }
-  else
-  {
-    int attributeIndex = theProvider->fieldNameIndex( mInterpolationAttributeComboBox->currentText() );
-    theInterpolator->enableAttributeValueInterpolation( attributeIndex );
-  }
-
   //create grid file writer
-  QgsGridFileWriter theWriter( theInterpolator, fileName, theVectorLayer->extent(), mNumberOfColumnsSpinBox->value(), mNumberOfRowsSpinBox->value() );
+  QgsGridFileWriter theWriter( theInterpolator, fileName, combinedLayerExtent, mNumberOfColumnsSpinBox->value(), mNumberOfRowsSpinBox->value() );
   if ( theWriter.writeFile( true ) == 0 )
   {
     mIface->addRasterLayer( fileName, "Interpolation" );
     accept();
   }
+
+  delete theInterpolator;
 }
 
 void QgsInterpolationDialog::on_mInputLayerComboBox_currentIndexChanged( const QString& text )
@@ -125,7 +174,8 @@
   mUseZCoordCheckBox->setEnabled( false );
 
   //get current vector layer
-  QgsVectorLayer* theVectorLayer = getCurrentVectorLayer();
+  QString currentComboText = mInputLayerComboBox->currentText();
+  QgsVectorLayer* theVectorLayer = vectorLayerFromName( currentComboText );
 
   if ( !theVectorLayer )
   {
@@ -164,6 +214,46 @@
   }
 }
 
+void QgsInterpolationDialog::on_mAddPushButton_clicked()
+{
+  //read active layer in mInputLayerComboBox
+  QString inputLayer = mInputLayerComboBox->currentText();
+
+  //read attribute / z-coordinate interpolation
+  QString interpolationAttribute;
+  if ( mUseZCoordCheckBox->checkState() == Qt::Checked )
+  {
+    interpolationAttribute = "Z_COORD";
+  }
+  else
+  {
+    interpolationAttribute = mInterpolationAttributeComboBox->currentText();
+  }
+
+  QTreeWidgetItem* newLayerItem = new QTreeWidgetItem();
+  newLayerItem->setText( 0, inputLayer );
+  newLayerItem->setText( 1, interpolationAttribute );
+
+  mLayersTreeWidget->addTopLevelItem( newLayerItem );
+  QComboBox* typeComboBox = new QComboBox();
+  typeComboBox->addItem( tr( "Points" ) );
+  typeComboBox->addItem( tr( "Structure lines" ) );
+  typeComboBox->addItem( tr( "Break lines" ) );
+  typeComboBox->setCurrentIndex( 0 );
+  mLayersTreeWidget->setItemWidget( newLayerItem, 2, typeComboBox );
+}
+
+void QgsInterpolationDialog::on_mRemovePushButton_clicked()
+{
+  QTreeWidgetItem* currentItem = mLayersTreeWidget->currentItem();
+  if ( !currentItem )
+  {
+    return;
+  }
+  delete currentItem;
+}
+
+
 void QgsInterpolationDialog::on_mOutputFileButton_clicked()
 {
   QString rasterFileName = QFileDialog::getSaveFileName( 0 );
@@ -181,16 +271,14 @@
   }
 }
 
-QgsVectorLayer* QgsInterpolationDialog::getCurrentVectorLayer()
+QgsVectorLayer* QgsInterpolationDialog::vectorLayerFromName( const QString& name )
 {
-  QString text = mInputLayerComboBox->currentText();
-
   QMap<QString, QgsMapLayer*> mapLayers = QgsMapLayerRegistry::instance()->mapLayers();
   QMap<QString, QgsMapLayer*>::iterator layer_it = mapLayers.begin();
 
   for ( ; layer_it != mapLayers.end(); ++layer_it )
   {
-    if ( layer_it.value()->name() == text )
+    if ( layer_it.value()->name() == name )
     {
       return dynamic_cast<QgsVectorLayer*>( layer_it.value() );
       break;

Modified: trunk/qgis/src/plugins/interpolation/qgsinterpolationdialog.h
===================================================================
--- trunk/qgis/src/plugins/interpolation/qgsinterpolationdialog.h	2009-07-30 11:08:18 UTC (rev 11210)
+++ trunk/qgis/src/plugins/interpolation/qgsinterpolationdialog.h	2009-07-30 11:30:33 UTC (rev 11211)
@@ -39,15 +39,17 @@
     void on_mOutputFileButton_clicked();
     void on_mConfigureInterpolationButton_clicked();
     void on_mInterpolationMethodComboBox_currentIndexChanged( const QString &text );
+    void on_mAddPushButton_clicked();
+    void on_mRemovePushButton_clicked();
 
   private:
     QgisInterface* mIface;
     /**Dialog to get input for the current interpolation method*/
     QgsInterpolatorDialog* mInterpolatorDialog;
 
-    /**Returns the vector layer that is selected in the layer combo box.
-     Returns 0 in case of error.*/
-    QgsVectorLayer* getCurrentVectorLayer();
+    /**Returns the vector layer object with the given name
+     Returns a pointer to the vector layer or 0 in case of error.*/
+    QgsVectorLayer* vectorLayerFromName( const QString& name );
 };
 
 #endif

Modified: trunk/qgis/src/plugins/interpolation/qgsinterpolationdialogbase.ui
===================================================================
--- trunk/qgis/src/plugins/interpolation/qgsinterpolationdialogbase.ui	2009-07-30 11:08:18 UTC (rev 11210)
+++ trunk/qgis/src/plugins/interpolation/qgsinterpolationdialogbase.ui	2009-07-30 11:30:33 UTC (rev 11211)
@@ -5,8 +5,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>485</width>
-    <height>372</height>
+    <width>538</width>
+    <height>577</height>
    </rect>
   </property>
   <property name="sizePolicy" >
@@ -18,7 +18,7 @@
   <property name="windowTitle" >
    <string>Interpolation plugin</string>
   </property>
-  <layout class="QGridLayout" >
+  <layout class="QGridLayout" name="gridLayout_2" >
    <item row="0" column="0" >
     <widget class="QGroupBox" name="mInputGroupBox" >
      <property name="sizePolicy" >
@@ -30,21 +30,18 @@
      <property name="title" >
       <string>Input</string>
      </property>
-     <layout class="QGridLayout" >
+     <layout class="QGridLayout" name="gridLayout" >
       <item row="0" column="0" >
-       <widget class="QLabel" name="mInputVectorLayerLabel" >
+       <widget class="QLabel" name="label_2" >
         <property name="text" >
-         <string>Input vector layer</string>
+         <string>Vector layers:</string>
         </property>
-        <property name="buddy" >
-         <cstring>mInputLayerComboBox</cstring>
-        </property>
        </widget>
       </item>
-      <item row="0" column="1" >
+      <item row="0" column="1" colspan="2" >
        <widget class="QComboBox" name="mInputLayerComboBox" >
         <property name="sizePolicy" >
-         <sizepolicy vsizetype="Fixed" hsizetype="MinimumExpanding" >
+         <sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
@@ -52,30 +49,16 @@
        </widget>
       </item>
       <item row="1" column="0" >
-       <widget class="QLabel" name="label" >
-        <property name="text" >
-         <string/>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="1" >
-       <widget class="QCheckBox" name="mUseZCoordCheckBox" >
-        <property name="text" >
-         <string>Use z-Coordinate for interpolation</string>
-        </property>
-       </widget>
-      </item>
-      <item row="2" column="0" >
        <widget class="QLabel" name="mInterpolationAttributeLabel" >
         <property name="text" >
-         <string>Interpolation attribute </string>
+         <string>Interpolation attribute:</string>
         </property>
         <property name="buddy" >
          <cstring>mInterpolationAttributeComboBox</cstring>
         </property>
        </widget>
       </item>
-      <item row="2" column="1" >
+      <item row="1" column="1" colspan="2" >
        <widget class="QComboBox" name="mInterpolationAttributeComboBox" >
         <property name="sizePolicy" >
          <sizepolicy vsizetype="Fixed" hsizetype="MinimumExpanding" >
@@ -85,6 +68,46 @@
         </property>
        </widget>
       </item>
+      <item row="2" column="0" colspan="3" >
+       <widget class="QCheckBox" name="mUseZCoordCheckBox" >
+        <property name="text" >
+         <string>Use z-Coordinate for interpolation</string>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="1" >
+       <widget class="QPushButton" name="mAddPushButton" >
+        <property name="text" >
+         <string>Add</string>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="2" >
+       <widget class="QPushButton" name="mRemovePushButton" >
+        <property name="text" >
+         <string>Remove</string>
+        </property>
+       </widget>
+      </item>
+      <item row="4" column="0" colspan="3" >
+       <widget class="QTreeWidget" name="mLayersTreeWidget" >
+        <column>
+         <property name="text" >
+          <string>Vector layer</string>
+         </property>
+        </column>
+        <column>
+         <property name="text" >
+          <string>Attribute</string>
+         </property>
+        </column>
+        <column>
+         <property name="text" >
+          <string>Type</string>
+         </property>
+        </column>
+       </widget>
+      </item>
      </layout>
     </widget>
    </item>
@@ -119,7 +142,8 @@
          <string>...</string>
         </property>
         <property name="icon" >
-         <iconset resource="interpolator.qrc" >:/options.png</iconset>
+         <iconset resource="interpolator.qrc" >
+          <normaloff>:/options.png</normaloff>:/options.png</iconset>
         </property>
        </widget>
       </item>
@@ -186,16 +210,13 @@
       <enum>Qt::Horizontal</enum>
      </property>
      <property name="standardButtons" >
-      <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
      </property>
     </widget>
    </item>
   </layout>
  </widget>
  <tabstops>
-  <tabstop>mInputLayerComboBox</tabstop>
-  <tabstop>mUseZCoordCheckBox</tabstop>
-  <tabstop>mInterpolationAttributeComboBox</tabstop>
   <tabstop>mInterpolationMethodComboBox</tabstop>
   <tabstop>mConfigureInterpolationButton</tabstop>
   <tabstop>mNumberOfColumnsSpinBox</tabstop>

Modified: trunk/qgis/src/plugins/interpolation/qgsinterpolator.cpp
===================================================================
--- trunk/qgis/src/plugins/interpolation/qgsinterpolator.cpp	2009-07-30 11:08:18 UTC (rev 11210)
+++ trunk/qgis/src/plugins/interpolation/qgsinterpolator.cpp	2009-07-30 11:30:33 UTC (rev 11211)
@@ -28,7 +28,7 @@
 #define isnan(f) _isnan(f)
 #endif
 
-QgsInterpolator::QgsInterpolator( const QList<QgsVectorLayer*>& vlayers ): mDataIsCached( false ), mVectorLayers( vlayers ), zCoordInterpolation( false ), mValueAttribute( -1 )
+QgsInterpolator::QgsInterpolator( const QList<LayerData>& layerData ): mLayerData( layerData )
 {
 
 }
@@ -43,15 +43,9 @@
 
 }
 
-void QgsInterpolator::enableAttributeValueInterpolation( int attribute )
-{
-  mValueAttribute = attribute;
-  zCoordInterpolation = false;
-}
-
 int QgsInterpolator::cacheBaseData()
 {
-  if ( mVectorLayers.size() < 1 )
+  if ( mLayerData.size() < 1 )
   {
     return 0;
   }
@@ -60,25 +54,25 @@
   mCachedBaseData.clear();
   mCachedBaseData.reserve( 100000 );
 
-  QList<QgsVectorLayer*>::iterator v_it = mVectorLayers.begin();
+  QList<LayerData>::iterator v_it = mLayerData.begin();
 
-  for ( ; v_it != mVectorLayers.end(); ++v_it )
+  for ( ; v_it != mLayerData.end(); ++v_it )
   {
-    if (( *v_it ) == 0 )
+    if ( v_it->vectorLayer == 0 )
     {
       continue;
     }
 
-    QgsVectorDataProvider* provider = ( *v_it )->dataProvider();
+    QgsVectorDataProvider* provider = v_it->vectorLayer->dataProvider();
     if ( !provider )
     {
       return 2;
     }
 
     QgsAttributeList attList;
-    if ( !zCoordInterpolation )
+    if ( !v_it->zCoordInterpolation )
     {
-      attList.push_back( mValueAttribute );
+      attList.push_back( v_it->interpolationAttribute );
     }
 
     provider->select( attList );
@@ -89,10 +83,10 @@
 
     while ( provider->nextFeature( theFeature ) )
     {
-      if ( !zCoordInterpolation )
+      if ( !v_it->zCoordInterpolation )
       {
         QgsAttributeMap attMap = theFeature.attributeMap();
-        QgsAttributeMap::const_iterator att_it = attMap.find( mValueAttribute );
+        QgsAttributeMap::const_iterator att_it = attMap.find( v_it->interpolationAttribute );
         if ( att_it == attMap.end() ) //attribute not found, something must be wrong (e.g. NULL value)
         {
           continue;
@@ -104,7 +98,7 @@
         }
       }
 
-      if ( addVerticesToCache( theFeature.geometry(), attributeValue ) != 0 )
+      if ( addVerticesToCache( theFeature.geometry(), v_it->zCoordInterpolation, attributeValue ) != 0 )
       {
         return 3;
       }
@@ -114,7 +108,7 @@
   return 0;
 }
 
-int QgsInterpolator::addVerticesToCache( QgsGeometry* geom, double attributeValue )
+int QgsInterpolator::addVerticesToCache( QgsGeometry* geom, bool zCoord, double attributeValue )
 {
   if ( !geom )
   {
@@ -136,7 +130,7 @@
       theVertex.x = *(( double * )( currentWkbPtr ) );
       currentWkbPtr += sizeof( double );
       theVertex.y = *(( double * )( currentWkbPtr ) );
-      if ( zCoordInterpolation && hasZValue )
+      if ( zCoord && hasZValue )
       {
         currentWkbPtr += sizeof( double );
         theVertex.z = *(( double * )( currentWkbPtr ) );
@@ -161,7 +155,7 @@
         currentWkbPtr += sizeof( double );
         theVertex.y = *(( double * )( currentWkbPtr ) );
         currentWkbPtr += sizeof( double );
-        if ( zCoordInterpolation && hasZValue ) //skip z-coordinate for 25D geometries
+        if ( zCoord && hasZValue ) //skip z-coordinate for 25D geometries
         {
           theVertex.z = *(( double * )( currentWkbPtr ) );
           currentWkbPtr += sizeof( double );

Modified: trunk/qgis/src/plugins/interpolation/qgsinterpolator.h
===================================================================
--- trunk/qgis/src/plugins/interpolation/qgsinterpolator.h	2009-07-30 11:08:18 UTC (rev 11210)
+++ trunk/qgis/src/plugins/interpolation/qgsinterpolator.h	2009-07-30 11:30:33 UTC (rev 11211)
@@ -44,8 +44,17 @@
       BREAK_LINES
     };
 
-    QgsInterpolator( const QList<QgsVectorLayer*>& vlayers );
+    /**A layer together with the information about interpolation attribute / z-coordinate interpolation and the type (point, structure line, breakline)*/
+    struct LayerData
+    {
+      QgsVectorLayer* vectorLayer;
+      bool zCoordInterpolation;
+      int interpolationAttribute;
+      InputType mInputType;
+    };
 
+    QgsInterpolator( const QList<LayerData>& layerData );
+
     virtual ~QgsInterpolator();
 
     /**Calculates interpolation value for map coordinates x, y
@@ -55,17 +64,9 @@
        @return 0 in case of success*/
     virtual int interpolatePoint( double x, double y, double& result ) = 0;
 
-    /**Use the z-coord of 25D for interpolation*/
-    void enableZCoordInterpolation() {zCoordInterpolation = true;}
-
     /**Use a vector attribute as interpolation value*/
     void enableAttributeValueInterpolation( int attribute );
 
-    /**Creates a vector layer that can be added to the main map, e.g. TIN edges for triangle interpolation.
-     Mouse clicks in the main map can be tracked and used for configuration (e.g. edge swaping). Default implementation does
-    nothing.*/
-    virtual QgsVectorLayer* createVectorLayer() const {return 0;}
-
   protected:
     /**Caches the vertex and value data from the provider. All the vertex data
      will be held in virtual memory
@@ -77,18 +78,19 @@
     /**Flag that tells if the cache already has been filled*/
     bool mDataIsCached;
 
+    //Information about the input vector layers and the attributes (or z-values) that are used for interpolation
+    QList<LayerData> mLayerData;
+
   private:
     QgsInterpolator(); //forbidden
     /**Helper method that adds the vertices of a geometry to the mCachedBaseData
        @param geom the geometry
+       @param zCoord true if the z-coordinate of the geometry is to be interpolated
        @param attributeValue the attribute value for interpolation (if not interpolated from z-coordinate)
      @return 0 in case of success*/
-    int addVerticesToCache( QgsGeometry* geom, double attributeValue );
+    int addVerticesToCache( QgsGeometry* geom, bool zCoord, double attributeValue );
 
-    QList<QgsVectorLayer*> mVectorLayers;
 
-    bool zCoordInterpolation;
-    int mValueAttribute;
 };
 
 #endif

Modified: trunk/qgis/src/plugins/interpolation/qgsinterpolatordialog.cpp
===================================================================
--- trunk/qgis/src/plugins/interpolation/qgsinterpolatordialog.cpp	2009-07-30 11:08:18 UTC (rev 11210)
+++ trunk/qgis/src/plugins/interpolation/qgsinterpolatordialog.cpp	2009-07-30 11:30:33 UTC (rev 11211)
@@ -27,7 +27,7 @@
 
 }
 
-void QgsInterpolatorDialog::setInputData( const QList< QPair <QgsVectorLayer*, QgsInterpolator::InputType> >& inputData )
+void QgsInterpolatorDialog::setInputData( const QList< QgsInterpolator::LayerData >& inputData )
 {
   mInputData = inputData;
 }

Modified: trunk/qgis/src/plugins/interpolation/qgsinterpolatordialog.h
===================================================================
--- trunk/qgis/src/plugins/interpolation/qgsinterpolatordialog.h	2009-07-30 11:08:18 UTC (rev 11210)
+++ trunk/qgis/src/plugins/interpolation/qgsinterpolatordialog.h	2009-07-30 11:30:33 UTC (rev 11211)
@@ -36,14 +36,14 @@
      The calling method takes ownership of the created interpolator and is responsible for its proper destruction*/
     virtual QgsInterpolator* createInterpolator() const = 0;
 
-    void setInputData( const QList< QPair <QgsVectorLayer*, QgsInterpolator::InputType> >& inputData );
+    void setInputData( const QList< QgsInterpolator::LayerData >& inputData );
 
   protected:
     /**Pointer to the running QGIS instance. This may be necessary to show interpolator properties on the map (e.g. triangulation)*/
     QgisInterface* mInterface;
 
-    /**A list of input data layers and their type (point, structure lines, breaklines)*/
-    QList< QPair <QgsVectorLayer*, QgsInterpolator::InputType> > mInputData;
+    /**A list of input data layers, their interpolation attribute and their type (point, structure lines, breaklines)*/
+    QList< QgsInterpolator::LayerData > mInputData;
 };
 
 #endif

Modified: trunk/qgis/src/plugins/interpolation/qgstininterpolator.cpp
===================================================================
--- trunk/qgis/src/plugins/interpolation/qgstininterpolator.cpp	2009-07-30 11:08:18 UTC (rev 11210)
+++ trunk/qgis/src/plugins/interpolation/qgstininterpolator.cpp	2009-07-30 11:30:33 UTC (rev 11211)
@@ -19,10 +19,14 @@
 #include "DualEdgeTriangulation.h"
 #include "LinTriangleInterpolator.h"
 #include "Point3D.h"
+#include "qgsfeature.h"
+#include "qgsgeometry.h"
 #include "qgssinglesymbolrenderer.h"
 #include "qgsvectorlayer.h"
+#include <QProgressDialog>
 
-QgsTINInterpolator::QgsTINInterpolator( const QList<QgsVectorLayer*>& inputData ): QgsInterpolator( inputData ), mTriangulation( 0 ), mTriangleInterpolator( 0 ), mIsInitialized( false )
+QgsTINInterpolator::QgsTINInterpolator( const QList<LayerData>& inputData, bool showProgressDialog ): QgsInterpolator( inputData ), mTriangulation( 0 ), \
+    mTriangleInterpolator( 0 ), mIsInitialized( false ), mShowProgressDialog( showProgressDialog )
 {
 }
 
@@ -55,36 +59,186 @@
 
 void QgsTINInterpolator::initialize()
 {
-  if ( !mDataIsCached )
+  DualEdgeTriangulation* theDualEdgeTriangulation = new DualEdgeTriangulation( 100000, 0 );
+  mTriangulation = theDualEdgeTriangulation;
+
+  //get number of features if we use a progress bar
+  int nFeatures = 0;
+  int nProcessedFeatures = 0;
+  if ( mShowProgressDialog )
   {
-    cacheBaseData();
+    QList<LayerData>::iterator layerDataIt = mLayerData.begin();
+    for ( ; layerDataIt != mLayerData.end(); ++layerDataIt )
+    {
+      if ( layerDataIt->vectorLayer )
+      {
+        nFeatures += layerDataIt->vectorLayer->featureCount();
+      }
+    }
   }
 
-  QList<Point3D*> rejectedPoints;
+  QProgressDialog* theProgressDialog = 0;
+  if ( mShowProgressDialog )
+  {
+    theProgressDialog = new QProgressDialog( QObject::tr( "Building triangulation..." ), QObject::tr( "Abort" ), 0, nFeatures, 0 );
+    theProgressDialog->setWindowModality( Qt::WindowModal );
+  }
 
-  //create DualEdgeTriangulation
 
-  DualEdgeTriangulation* theDualEdgeTriangulation = new DualEdgeTriangulation( mCachedBaseData.size(), 0 );
-  mTriangulation = theDualEdgeTriangulation;
+  QgsFeature f;
+  QList<LayerData>::iterator layerDataIt = mLayerData.begin();
+  for ( ; layerDataIt != mLayerData.end(); ++layerDataIt )
+  {
+    if ( layerDataIt->vectorLayer )
+    {
+      QgsAttributeList attList;
+      if ( !layerDataIt->zCoordInterpolation )
+      {
+        attList.push_back( layerDataIt->interpolationAttribute );
+      }
+      layerDataIt->vectorLayer->select( attList );
+      while ( layerDataIt->vectorLayer->nextFeature( f ) )
+      {
+        if ( mShowProgressDialog )
+        {
+          if ( theProgressDialog->wasCanceled() )
+          {
+            break;
+          }
+          theProgressDialog->setValue( nProcessedFeatures );
+        }
+        insertData( &f, layerDataIt->zCoordInterpolation, layerDataIt->interpolationAttribute, layerDataIt->mInputType );
+        ++nProcessedFeatures;
+      }
+    }
+  }
 
-  //add all the vertices to the triangulation
-  QVector<vertexData>::const_iterator vertex_it = mCachedBaseData.constBegin();
-  for ( ; vertex_it != mCachedBaseData.constEnd(); ++vertex_it )
+  delete theProgressDialog;
+  mTriangleInterpolator = new LinTriangleInterpolator( theDualEdgeTriangulation );
+  mIsInitialized = true;
+
+  //debug
+  //theDualEdgeTriangulation->saveAsShapefile("/home/marco/tmp/tin.shp");
+}
+
+int QgsTINInterpolator::insertData( QgsFeature* f, bool zCoord, int attr, InputType type )
+{
+  if ( !f )
   {
-    Point3D* thePoint = new Point3D( vertex_it->x, vertex_it->y, vertex_it->z );
-    if(mTriangulation->addPoint( thePoint ) == -100)
+    return 1;
+  }
+
+  QgsGeometry* g = f->geometry();
+  {
+    if ( !g )
     {
-      rejectedPoints.push_back(new Point3D(vertex_it->x, vertex_it->y, vertex_it->z));
+      return 2;
     }
   }
 
-  QList<Point3D*>::iterator rejectedIt = rejectedPoints.begin();
-  for(; rejectedIt != rejectedPoints.end(); ++rejectedIt)
+  //check attribute value
+  double attributeValue = 0;
+  bool attributeConversionOk = false;
+  if ( !zCoord )
   {
-    mTriangulation->addPoint(*rejectedIt);
+    QgsAttributeMap attMap = f->attributeMap();
+    QgsAttributeMap::const_iterator att_it = attMap.find( attr );
+    if ( att_it == attMap.end() ) //attribute not found, something must be wrong (e.g. NULL value)
+    {
+      return 3;
+    }
+    attributeValue = att_it.value().toDouble( &attributeConversionOk );
+    if ( !attributeConversionOk || isnan( attributeValue ) ) //don't consider vertices with attributes like 'nan' for the interpolation
+    {
+      return 4;
+    }
   }
 
-  mTriangleInterpolator = new LinTriangleInterpolator( theDualEdgeTriangulation );
+  //parse WKB. We cannot use the methods with QgsPoint because they don't contain z-values for 25D types
+  bool hasZValue = false;
+  double x, y, z;
+  unsigned char* currentWkbPtr = g->asWkb();
 
-  mIsInitialized = true;
+  QGis::WkbType wkbType = g->wkbType();
+  switch ( wkbType )
+  {
+    case QGis::WKBPoint25D:
+      hasZValue = true;
+    case QGis::WKBPoint:
+    {
+      currentWkbPtr += ( 1 + sizeof( int ) );
+      x = *(( double * )( currentWkbPtr ) );
+      currentWkbPtr += sizeof( double );
+      y = *(( double * )( currentWkbPtr ) );
+      if ( zCoord && hasZValue )
+      {
+        currentWkbPtr += sizeof( double );
+        z = *(( double * )( currentWkbPtr ) );
+      }
+      else
+      {
+        z = attributeValue;
+      }
+      Point3D* thePoint = new Point3D( x, y, z );
+      if ( mTriangulation->addPoint( thePoint ) == -100 )
+      {
+        return -1;
+      }
+      break;
+    }
+    case QGis::WKBLineString25D:
+      hasZValue = true;
+    case QGis::WKBLineString:
+    {
+      //maybe a structure or break line
+      Line3D* line = 0;
+      if ( type != POINTS )
+      {
+        line = new Line3D();
+      }
+      currentWkbPtr += ( 1 + sizeof( int ) );
+      int* npoints = ( int* )currentWkbPtr;
+      currentWkbPtr += sizeof( int );
+      for ( int index = 0;index < *npoints;++index )
+      {
+        x = *(( double * )( currentWkbPtr ) );
+        currentWkbPtr += sizeof( double );
+        y = *(( double * )( currentWkbPtr ) );
+        currentWkbPtr += sizeof( double );
+        if ( zCoord && hasZValue ) //skip z-coordinate for 25D geometries
+        {
+          z = *(( double * )( currentWkbPtr ) );
+        }
+        else
+        {
+          z = attributeValue;
+        }
+        if ( hasZValue )
+        {
+          currentWkbPtr += sizeof( double );
+        }
+
+        if ( type == POINTS )
+        {
+          //todo: handle error code -100
+          mTriangulation->addPoint( new Point3D( x, y, z ) );
+        }
+        else
+        {
+          line->insertPoint( new Point3D( x, y, z ) );
+        }
+      }
+
+      if ( type != POINTS )
+      {
+        mTriangulation->addLine( line, type == BREAK_LINES );
+      }
+      break;
+    }
+  }
+
+  //todo: add the same for multiline, polygon, multipolygon
+
+  return 0;
 }
+

Modified: trunk/qgis/src/plugins/interpolation/qgstininterpolator.h
===================================================================
--- trunk/qgis/src/plugins/interpolation/qgstininterpolator.h	2009-07-30 11:08:18 UTC (rev 11210)
+++ trunk/qgis/src/plugins/interpolation/qgstininterpolator.h	2009-07-30 11:30:33 UTC (rev 11211)
@@ -22,12 +22,13 @@
 
 class Triangulation;
 class TriangleInterpolator;
+class QgsFeature;
 
 /**Interpolation in a triangular irregular network*/
 class QgsTINInterpolator: public QgsInterpolator
 {
   public:
-    QgsTINInterpolator( const QList<QgsVectorLayer*>& inputData );
+    QgsTINInterpolator( const QList<LayerData>& inputData, bool showProgressDialog = false );
     ~QgsTINInterpolator();
 
     /**Calculates interpolation value for map coordinates x, y
@@ -41,8 +42,17 @@
     Triangulation* mTriangulation;
     TriangleInterpolator* mTriangleInterpolator;
     bool mIsInitialized;
+    bool mShowProgressDialog;
 
+    /**Create dual edge triangulation*/
     void initialize();
+    /**Inserts the vertices of a geometry into the triangulation
+      @param g the geometry
+      @param zCoord true if the z coordinate is the interpolation attribute
+      @param attr interpolation attribute index (if zCoord is false)
+      @param type point/structure line, break line
+      @return 0 in case of success, -1 if the feature could not be inserted because of numerical problems*/
+    int insertData( QgsFeature* f, bool zCoord, int attr, InputType type );
 };
 
 #endif

Modified: trunk/qgis/src/plugins/interpolation/qgstininterpolatordialog.cpp
===================================================================
--- trunk/qgis/src/plugins/interpolation/qgstininterpolatordialog.cpp	2009-07-30 11:08:18 UTC (rev 11210)
+++ trunk/qgis/src/plugins/interpolation/qgstininterpolatordialog.cpp	2009-07-30 11:30:33 UTC (rev 11211)
@@ -33,14 +33,6 @@
 
 QgsInterpolator* QgsTINInterpolatorDialog::createInterpolator() const
 {
-  QList<QgsVectorLayer*> inputLayerList;
-
-  QList< QPair <QgsVectorLayer*, QgsInterpolator::InputType> >::const_iterator data_it = mInputData.constBegin();
-  for ( ; data_it != mInputData.constEnd(); ++data_it )
-  {
-    inputLayerList.push_back( data_it->first );
-  }
-
-  QgsTINInterpolator* theInterpolator = new QgsTINInterpolator( inputLayerList );
+  QgsTINInterpolator* theInterpolator = new QgsTINInterpolator( mInputData, true );
   return theInterpolator;
 }



More information about the QGIS-commit mailing list