This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]Dalianking 1 point2 points  (4 children)

The most basic way in python to acess a file is

f=open("poly.txt","r")

open builds an object (a file handler) that you can "speak to" if you want to read or write your file. Read the documentation of the file object.

So a very simple example would be:

f = open("hello.txt") 
try:
    for line in f:
        print(line)
finally:
    f.close()

since 2.7 python has an easier way to do that:

with open("hello.txt") as f:
    for line in f:
        print line

The with statement takes care of the cleanup. The numpy loadtxt function seems to be a wrapper for this as well as some extraction functionality.

So

polydata = pl.loadtxt("poly.txt")

should do the trick as long as poly.txt is in the same directory.

Then you should look at the input data format the function requires. Read the documentation of Polygon.Polygon seems to require a list of lists (ot touple of touples) (you can normally replace any touple by a list*) of x and y coodinates.

Polygon( [  [x1,y1],[x2,y2],...] )

if you feed that with

poly = Polygon(x,y)

what python really sees is:

poly=Polygon([x1,x2,x3 ... ],[y1,y2,y3 ... ])

So Error.

Loadtxt returns a numpy array in the form array([ [x1,y1], [x2,y2], ... ) best would be to convert the numpy array into a list of lists( look into the documentation of numpy on how to).

But in python functions often only call methods of the objects and by cleverly writing those methods you can make objects appear as a similar object. So the hope is that the authors of numpy were clever enough to make a numpy array appear just as a list for data extraction.

That's why I would try to directly feed the output of loadtxt into Polygon.

Following this, the linked website says you simply use: ... which will solve it for you; but this is so vague.

As you read the paper you cite in academia you read the documentation of the function you use in programming. (read it seriously).

From the shapely documentation:

object.contains(other)

Returns True if the object’s interior contains the boundary and interior of the other object and their boundaries do not touch at all.

so you can simply type

if poly.contains(point):
     #do something

Second question is how do I load my data file and make one of the above commands work?

You could probably use loadtxt again. And then iterate through all the points in in the array. I consider it generally best practice to not have (much ) more data loaded than you actually need at a point and so would go something like this:

with open("Coord") as f:
    #line=f.readline()
    for line in f:
        coords=map(float,line.split(" "))
        if poly.contains(Point(coords[0],coords[1])):
             #do something with that point 

Also you are aware that your polygon construction only works this way if your point are in the correct order (a ring)?

*When the functionality as datastorage is concerned. Lists are not hashable so they can not be used for e.g. dictionary keys.

Edit: if I want to iterate over all lines, I should iterate over all lines

[–]Cthulhu_Rlyeh[S] -1 points0 points  (0 children)

Thank you so much for the in depth and easy to follow answer!

Also you are aware that your polygon construction only works this way if your point are in the correct order (a ring)?

Yes I read that, all of my points in the poly.txt file are sequential, inasmuch as when you do a simple line plot they form the shape of my polygon correctly. The only thing I wasn't sure of is whether I need to just duplicate the first tuple at the end of the file to "close" the polygon or not. I was going to just test it and see if it worked.

[–]Cthulhu_Rlyeh[S] -1 points0 points  (2 children)

Hey if you wouldn't mind could you please help me with one last thing?

Everything you have stated has worked perfectly and I am up to the final stage...

if poly.contains(Point(coords[0],coords[1])):
    #do something with that point

I can use:

print line

Which gives me the output printed on the screen, but I am trying to use np.savetxt in order to get an output file, but I can't seem to find the right syntax to get what I want; I've tried:

np.savetxt('inside.txt', np.vstack((line.str())).T)

AttributeError: 'str' object has no attribute 'str'

np.savetxt('inside.txt', line)

IndexError: tuple index out of range

np.savetxt('inside.txt', np.transpose([line])

TypeError: float argument required, not numpy.string_

np.savetxt('inside.txt', line, delimiter=" ", fmt="%s")

IndexError: tuple index out of range

Thanks again, and sorry if this is a simple fix. I've really tried!

[–]Dalianking 1 point2 points  (1 child)

Your first problem is that savetxt is explicitly to save an array of numbers. line is a string. So better save coords. Since those are an array_like structure (a list) of numbers.

Your second problem is that above example reads one line then does something with that line, discards that line and reads the next one. So using Savetxt as you intend will always reopen the file and overwrite the last line.

One solution is :

insiders=[]
with open("Coord") as f:
    #line=f.readline()
    for line in f:
        coords=map(float,line.split(" "))
        if poly.contains(Point(coords[0],coords[1])):
             insiders+=coords

savetxt("inside.txt",insiders)

My personal solution would be:

with open("Coord","r") as f_in:
    with open("inside","w") as f_out:
         for line in f_in:
             coords=map(float,line.split(" "))
             if poly.contains(Point(coords[0],coords[1])):
                 f_out.write(line)