Pregunta

I'm trying to create a script in python to find out if points lay within or outside a polygon where the four corners are designated by the user, and then count how many fall into each category. So far my code looks like this, which I have adopted from the Ray Casting Method:

    import csv


    def point_in_polygon(x,y,poly):
    n = len(poly)
    inside = False

    point_x1,point_y1 = poly[0]
    for i in range(n+1):
        point_x2,point_y2 = poly[i % n]
        if y > min(point_y1,point_y2):
            if y <= max(point_y1,point_y2):
                if x <= max(point_x1,point_x2):
                    if point_y1 != point_y2:
                        xints = (y-point_y1)*(point_x2 - point_x1)/(point_y2-point_y1)+point_x1
                    if point_x1 == point_x2 or x <= xints:
                        inside = not inside
        point_x1,point_y1= point_x2,point_y2

    return inside

def a_reader():
    a_reader = open(r'datasmall.csv', 'rU')
    a_csv_reader = csv.reader(a_reader)
    a_csv_reader.next()

    numRecords = sum(1 for line in open('datasmall.csv'))
    print (numRecords - 1, "<-- This is the number of stations")

    for row in a_csv_reader:
        return row

    a_reader.close()

a_reader()

## Input goes here. Will update all inputs after running properly

def main():

    x1 = input('What is X1?')
    y1 = input('What is Y1?')

    polygon = [(x1,y1),(10,10),(10,0),(0,0)]

    for row in a_reader:
        print point_in_polygon(float(row[1]), float(row[2]),polygon,)

main()

When broken down into stubs, all the separate parts work. My problem is when I'm trying to use my CSV file with a list of coordinates to see if they land inside the polygon and the values from the CSV file aren't being converted into floats. The error I receive is this

Traceback (most recent call last):
  File "C:\Python27\Lib\site-packages\Pythonwin\pywin\framework\scriptutils.py", line 323, in RunScript
    debugger.run(codeObject, __main__.__dict__, start_stepping=0)
  File "C:\Python27\Lib\site-packages\Pythonwin\pywin\debugger\__init__.py", line 60, in run
    _GetCurrentDebugger().run(cmd, globals,locals, start_stepping)
  File "C:\Python27\Lib\site-packages\Pythonwin\pywin\debugger\debugger.py", line 655, in run
    exec cmd in globals, locals
  File "E:\spatial\Project\xy_input_list.py", line 16, in <module>
    import csv
  File "E:\spatial\Project\xy_input_list.py", line 62, in main
    for row in a_reader:
TypeError: 'function' object is not iterable

Now does this mean that in main() it isn't able pass the values from the CSV file to the point_in_polygon function?

The CSV file I've been using to practice is as such, as the one I'm hoping to use have many more values:

ID,Easting,Northing
1,10,10
2,1,2
3,5,5
4,6,3
5,4,0
6,4,9
7,0,0

I've managed to get the float method to work in other programs but I'm wondering if there is something I'm missing with ray casting that is making them clash somehow. Any help will be greatly appreciated.

¿Fue útil?

Solución

Looks like you need to change

for row in a_reader:
...

to

for row in a_reader():
...

Otros consejos

You need to call a_reader to get the row it returns:

for row in a_reader():
                 # ^ note parentheses

Also, that function can be improved - the close never explicitly runs, as it is after return, and you should yield each row rather than just returning the first one:

def a_reader(filename="datasmall.csv"):
    with open(filename) as f:
        numRecords = sum(1 for line in f)
    print("{0} <-- This is the number of stations".format(numRecords-1))
    with open(filename) as reader:
        csv_reader = csv.reader(reader)
        csv_reader.next()
        for row in csv_reader:
            yield row
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top