Skip to content

Commit

Permalink
starting to implement different transformations
Browse files Browse the repository at this point in the history
  • Loading branch information
olivierdalang committed May 26, 2014
1 parent 75b9d94 commit c8a4757
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 39 deletions.
39 changes: 33 additions & 6 deletions ui_main.ui
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@
</item>
</layout>
</item>
<item row="2" column="0" colspan="2">
<item row="3" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Transformation type</string>
Expand All @@ -148,7 +148,7 @@
<item>
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
<number>3</number>
<number>0</number>
</property>
<widget class="QWidget" name="page_0">
<layout class="QHBoxLayout" name="horizontalLayout_7">
Expand All @@ -164,7 +164,7 @@
</font>
</property>
<property name="text">
<string>Invalid - 0 pairs</string>
<string>Invalid. Please define pairs by creating lines in the pairs layers.</string>
</property>
<property name="textFormat">
<enum>Qt::AutoText</enum>
Expand Down Expand Up @@ -305,7 +305,7 @@
</layout>
</widget>
</item>
<item row="3" column="0" colspan="2">
<item row="4" column="0" colspan="2">
<widget class="QPushButton" name="runButton">
<property name="text">
<string>Run</string>
Expand All @@ -315,7 +315,7 @@
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<item row="5" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string/>
Expand All @@ -341,7 +341,7 @@
</layout>
</widget>
</item>
<item row="5" column="0">
<item row="6" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
Expand All @@ -354,6 +354,33 @@
</property>
</spacer>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Change pairs to pins</string>
</property>
</widget>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QCheckBox" name="pairsToPinsCheckBox">
<property name="minimumSize">
<size>
<width>0</width>
<height>22</height>
</size>
</property>
<property name="text">
<string>(not recommended if you restrict to selection)</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
Expand Down
117 changes: 86 additions & 31 deletions vectorbender.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@ def __init__(self, iface):
self.ptsA = []
self.ptsB = []

self.delaunay = []
self.delaunay = None
self.linear = None
self.translation = None

self.aboutWindow = None

self.rubberBands = None
Expand Down Expand Up @@ -125,6 +128,25 @@ def loadDelaunay(self, pairsLayer, buff=0):
self.expandedHull = self.hull

self.delaunay = matplotlib.tri.Triangulation([p.x() for p in self.ptsA],[p.y() for p in self.ptsA])
def loadLinear(self, pairsLayer):
features = pairsLayer.getFeatures() if not self.dlg.restrictBox_pairsLayer.isChecked() else pairsLayer.selectedFeatures()

u,v = None, None
for i,f in enumerate(features): #we can't use features[0] and features[1] because QgsFeatureIterator object does not support indexing
if u is None:
u = f.geometry().asPolyline()
elif v is None:
v = f.geometry().asPolyline()
else:
break
self.linear = ((u[0], u[-1]),(v[0], v[-1]))
def loadTranslation(self, pairsLayer):
features = pairsLayer.getFeatures() if not self.dlg.restrictBox_pairsLayer.isChecked() else pairsLayer.selectedFeatures()

for f in features: #we can't use features[0] because QgsFeatureIterator object does not support indexing
v = f.geometry().asPolyline()
self.translation = (v[-1].x()-v[0].x(), v[-1].y()-v[0].y())
break

def determineTransformationType(self):

Expand Down Expand Up @@ -208,15 +230,23 @@ def run(self):
toBendLayer = self.dlg.toBendLayer()
pairsLayer = self.dlg.pairsLayer()


transType = self.determineTransformationType()

# Loading the delaunay
self.dlg.displayMsg( "Loading delaunay mesh (%i points) ..." % len(self.ptsA) )
QCoreApplication.processEvents()
self.loadDelaunay(pairsLayer, self.dlg.bufferValue())
self.trifinder = self.delaunay.get_trifinder()


if transType==3:
self.dlg.displayMsg( "Loading delaunay mesh (%i points) ..." % len(self.ptsA) )
QCoreApplication.processEvents()
self.loadDelaunay(pairsLayer, self.dlg.bufferValue())
self.trifinder = self.delaunay.get_trifinder()
elif transType==2:
self.dlg.displayMsg( "Loading linear transformation vectors..." )
self.loadLinear(pairsLayer)
elif transType==1:
self.dlg.displayMsg( "Loading translation vector..." )
self.loadTranslation(pairsLayer)
else:
self.dlg.displayMsg( "INVALID TRANSFORMATION TYPE - YOU SHOULDN'T HAVE BEEN ABLE TO HIT RUN" )
return

# Starting to iterate
features = toBendLayer.getFeatures() if not self.dlg.restrictBox_toBendLayer.isChecked() else toBendLayer.selectedFeatures()
Expand All @@ -234,21 +264,21 @@ def run(self):

geom = feature.geometry()

#TODO : this cood be much simpler if we could iterate through to vertices and use QgsGeometry.moveVertex(x,y,index), but QgsGeometry.vertexAt(index) doesn't tell wether the index exists, so there's no clean way to iterate...
#TODO : this cood be much simple if we could iterate through to vertices and use QgsGeometry.moveVertex(x,y,index), but QgsGeometry.vertexAt(index) doesn't tell wether the index exists, so there's no clean way to iterate...

if geom.type() == QGis.Point:

if not geom.isMultipart():
# SINGLE PART POINT
p = goem.asPoint()
newGeom = QgsGeometry.fromPoint( self.mapPoint( p ) )
newGeom = QgsGeometry.fromPoint( self.mapPoint(p, transType) )

else:
# MULTI PART POINT
listA = geom.asMultiPoint()
newListA = []
for p in listA:
newListA.append( self.mapPoint(p) )
newListA.append( self.mapPoint(p, transType) )
newGeom = QgsGeometry.fromMultiPoint( newListA )

elif geom.type() == QGis.Line:
Expand All @@ -258,7 +288,7 @@ def run(self):
listA = geom.asPolyline()
newListA = []
for p in listA:
newListA.append( self.mapPoint(p) )
newListA.append( self.mapPoint(p, transType) )
newGeom = QgsGeometry.fromPolyline( newListA )

else:
Expand All @@ -268,7 +298,7 @@ def run(self):
for listB in listA:
newListB = []
for p in listB:
newListB.append( self.mapPoint(p) )
newListB.append( self.mapPoint(p, transType) )
newListA.append( newListB )
newGeom = QgsGeometry.fromMultiPolyline( newListA )

Expand All @@ -281,7 +311,7 @@ def run(self):
for listB in listA:
newListB = []
for p in listB:
newListB.append( self.mapPoint(p) )
newListB.append( self.mapPoint(p, transType) )
newListA.append( newListB )
newGeom = QgsGeometry.fromPolygon( newListA )

Expand All @@ -294,7 +324,7 @@ def run(self):
for listC in listB:
newListC = []
for p in listC:
newListC.append( self.mapPoint(p) )
newListC.append( self.mapPoint(p, transType) )
newListB.append( newListC )
newListA.append( newListB )
newGeom = QgsGeometry.fromMultiPolygon( newListA )
Expand All @@ -309,32 +339,45 @@ def run(self):


#Transforming pairs to pins
features = pairsLayer.getFeatures() if not self.dlg.restrictBox_pairsLayer.isChecked() else pairsLayer.selectedFeatures()
if self.dlg.pairsToPinsCheckBox.isChecked():

count = pairsLayer.featureCount() if not self.dlg.restrictBox_pairsLayer.isChecked() else len(features)
self.dlg.progressBar.setValue( 0 )
self.dlg.displayMsg( "Starting to transform %i pairs to pins..." % count )
QCoreApplication.processEvents()
features = pairsLayer.getFeatures() if not self.dlg.restrictBox_pairsLayer.isChecked() else pairsLayer.selectedFeatures()

pairsLayer.beginEditCommand("Transforming pairs to pins")
for i,feature in enumerate(features):

self.dlg.progressBar.setValue( int(100.0*float(i)/float(count)) )
self.dlg.displayMsg( "Transforming pair to pin %i out of %i..." % (i, count))
count = pairsLayer.featureCount() if not self.dlg.restrictBox_pairsLayer.isChecked() else len(features)
self.dlg.progressBar.setValue( 0 )
self.dlg.displayMsg( "Starting to transform %i pairs to pins..." % count )
QCoreApplication.processEvents()

geom = feature.geometry().asPolyline()
pairsLayer.beginEditCommand("Transforming pairs to pins")
for i,feature in enumerate(features):

newGeom = QgsGeometry.fromPolyline( [geom[-1],geom[-1]] )
pairsLayer.changeGeometry( feature.id(), newGeom )
self.dlg.progressBar.setValue( int(100.0*float(i)/float(count)) )
self.dlg.displayMsg( "Transforming pair to pin %i out of %i..." % (i, count))
QCoreApplication.processEvents()

pairsLayer.endEditCommand()
geom = feature.geometry().asPolyline()

newGeom = QgsGeometry.fromPolyline( [geom[-1],geom[-1]] )
pairsLayer.changeGeometry( feature.id(), newGeom )

pairsLayer.endEditCommand()

self.dlg.displayMsg( "Finished !" )
self.dlg.progressBar.setValue( 100 )
pairsLayer.repaintRequested.emit()

def mapPoint(self, p):
def mapPoint(self, p, transType):

if transType == 3:
return self.mapPointBend(p)
if transType == 2:
return self.mapPointLinear(p)
if transType == 1:
return self.mapPointTranslate(p)

return QgsPoint(p[0], p[1])

def mapPointBend(self, p):

tri = self.trifinder( p[0], p[1] )

Expand All @@ -354,6 +397,14 @@ def mapPoint(self, p):
mappedP = mapPointFromTriangleAtoTriangleB(p, a1, a2, a3, b1, b2, b3)

return QgsPoint(mappedP[0], mappedP[1])

def mapPointLinear(self, p):
return QgsPoint(p[0], p[1])

def mapPointTranslate(self, p):
return QgsPoint(p[0]+self.translation[0], p[1]+self.translation[1])





Expand All @@ -378,4 +429,8 @@ def fromTriangularToCartesian(l,t1,t2,t3):
""" l is a triplet for barycentric coordinates """
x = l[0]*t1.x()+l[1]*t2.x()+l[2]*t3.x()
y = l[0]*t1.y()+l[1]*t2.y()+l[2]*t3.y()
return (x,y)
return (x,y)




5 changes: 3 additions & 2 deletions vectorbenderdialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ def __init__(self, iface, vb):
self.editModeButton_pairsLayer.clicked.connect(self.checkRequirements)
self.editModeButton_toBendLayer.clicked.connect(self.checkRequirements)
self.comboBox_toBendLayer.activated.connect( self.checkRequirements )
self.pairsToPinsCheckBox.clicked.connect( self.checkRequirements )

# When those are changed, we change the transformation type (which also checks the requirements)

Expand Down Expand Up @@ -88,8 +89,8 @@ def checkRequirements(self):
if not tbl.isEditable():
self.displayMsg( "The layer to bend must be in edit mode !", True )
return
if not pl.isEditable():
self.displayMsg( "The pairs layer must be in edit mode !", True )
if not pl.isEditable() and self.pairsToPinsCheckBox.isChecked():
self.displayMsg( "The pairs layer must be in edit mode if you want to change pairs to pins !", True )
return
if self.stackedWidget.currentIndex() == 0:
self.displayMsg("Impossible to run with an invalid transformation type.", True)
Expand Down

0 comments on commit c8a4757

Please sign in to comment.