Looks like you need to change
for row in a_reader:
...
to
for row in a_reader():
...
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.
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 return
ing 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