Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I have a loop which calculates two points for each iteration (x3,y3) and (x4,y4). As seen in the code these two points are added for each iteration, which gives i-1 lines. Each line has a individual id.

What I want is to add all these points at the same time, so it makes one polyline with only one id. This is done by adding all the points in the line:

fet.setGeometry( QgsGeometry.fromMultiPolyline([[QgsPoint(x3,y3), QgsPoint(x4,y4)]]))

instead of only these two points at the time. But I can not figure out how to change the loop to make it work. I guess for each iteration, I have to save a string with QgsPoint(x3,y3), QgsPoint(x4,y4) for the given iteration and add the next two points as a string in the next iteration. But I can not see how?

for i in range(0,len(points)-1):
    coor1 = points[i]
    x1 = coor1[0]
    y1 = coor1[1]
    dist = 0
    coor2 = points[i+1]
    x2 = coor2[0]
    y2 = coor2[1]
    dn = ((x1-x2)**2 + (y1-y1)**2)**0.5
    x3 = x1 + dist*(y1-y2) / dn
    y3 = y1 - dist*(x1-x2) / dn     
    x4 = x2 + dist*(y1-y2) / dn
    y4 = y2 - dist*(x1-x2) / dn  

    fet.setGeometry( QgsGeometry.fromMultiPolyline([[QgsPoint(x3,y3), QgsPoint(x4,y4)]]))
    pr.addFeatures( [ fet ] )
share|improve this question
1  
Can you clarify what you need to do a bit more please? Do you want to build out a polygon as you go though each iteration? –  Nathan W Apr 1 '13 at 7:59
    
Yes, I want to build a polyline with only one id. The polyline should contain all x3,y3 and x4,y4 for all i. –  Toke Apr 3 '13 at 1:02
add comment

2 Answers 2

use a Python iterator. See How to calculate distances in a point sequence? or How do I find vector line bearing in QGIS or GRASS?

example (iterator from Most pythonic way to get the previous element):

# iterator 
def pair_points(iterable):
    prev = None
    for elem in iterable:
        yield prev, elem
        prev = elem

Application with a simple example:

points = ((1,2),(3,4),(5,6),(7,8))
for pt in pair_points(points):
    print pt
 (None, (1, 2))
 ((1, 2), (3, 4))
 ((3, 4), (5, 6))
 ((5, 6), (7, 8))

So, to avoid the None

for i, pair in enumerate(pair_points(points)):
    if i > 0: # None
        print pair
 ((1, 2), (3, 4))
 ((3, 4), (5, 6))
 ((5, 6), (7, 8))

and in your case:

def new_point(point1,point2):
   dist = 0
   x1,y1 = point1
   x2,y2 = point2
   dn = ((x1-x2)**2 + (y1-y1)**2)**0.5
   x3 = x1 + dist*(y1-y2) / dn
   y3 = y1 - dist*(x1-x2) / dn     
   x4 = x2 + dist*(y1-y2) / dn
   y4 = y2 - dist*(x1-x2) / dn
   return x3,y3,x4,y4    

for i, pair in enumerate(pair_points(points)):
    if i > 0:
       x3,y3, x4,y4 = new_point(pair[0],pair[1])
       fet.setGeometry( QgsGeometry.fromMultiPolyline([[QgsPoint(x3,y3), QgsPoint(x4,y4)]]))
       pr.addFeatures( [ fet ] )

But I don't understand the dist = 0 because:

x3 = x1 + dist*(y1-y2) / dn = x1 /dn
share|improve this answer
    
You can even do: gist.github.com/NathanW2/5284046 with the x3, y3, etc lines. Just for a bit of clean up. –  Nathan W Apr 1 '13 at 9:47
    
yes but with dist = 0 it is the same as x3, y3, x4, y4 = (x1 / dn, y1 / dn, x2/ dn, y2/ dn) –  gene Apr 1 '13 at 9:52
    
true even better :) –  Nathan W Apr 1 '13 at 9:58
add comment

The dist is not zero, I just forgot to give it a number. The example you give works, but it does not do what I want. What I want is to get the following line:

fet.setGeometry(QgsGeometry.fromMultiPolyline([[QgsPoint(x3,y3), QgsPoint(x4,y4), Qgspoint(x3,y3), QgsPoint(x4,y4), Qgs...)]])) 

I want only one setGeometry line with all the x3,y3 and x4,y4 generated for each i. So all these lines have the same id. I hope it makes sense. It is my first python code, and are soooo close to make it work :D

Another possibility maybe is to this for each single point:

 fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(x3,y3))
 pr.addFeatures( [ fet ] )

and afterwards convert this to a polyline. But I do not know if that can be done.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.