check if polygon is closed fails
Nikolaus opened this issue · 1 comments
PyShp Version
2.3.1
Python Version
3.10.7
Your code
with shp.Writer(path[:-4]+'_offset.shp', shapefile.POLYGON) as writer:
writer.field('name', 'C')
writer.poly([points.T])
writer.record('polygon1')Full stacktrace
Traceback (most recent call last):
File "/home/horn/develop/antelope/zamg_antelope/scripts/./shapeoffset.py", line 154, in <module>
main()
File "/home/horn/develop/antelope/zamg_antelope/scripts/./shapeoffset.py", line 150, in main
save_offset(args.path, offseted)
File "/home/horn/develop/antelope/zamg_antelope/scripts/./shapeoffset.py", line 118, in save_offset
writer.poly([points.T])
File "/opt/antelope/python3.10.7/lib/python3.10/site-packages/shapefile.py", line 2464, in poly
self._shapeparts(parts=polys, shapeType=shapeType)
File "/opt/antelope/python3.10.7/lib/python3.10/site-packages/shapefile.py", line 2524, in _shapeparts
if part[0] != part[-1]:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()Other notes
Obviously, the problem here is comparing two array with multiple elements. A dumb would be to compare all elements like here:
for part in parts:
# if part[0] != part[-1]:
append = False
for ndx in range(len/part[0])):
if part[0][ndx] != part[-1][ndx]:
append = True
if append:
part.append(part[0])
Nikolaus, does PyShp claim to support numpy arrays?
The only examples I can find in the PyShp docs, show that a point passed to a shapefile.Writer method, must be a native Python list of numbers, not a numpy array.
Make a feature request issue for numpy.array support if you like, to see if there's any support or enthusiasm for adding that. In my opinion, as PyShp still supports Python 2 as well as Python 3, the old Python 2 versions of numpy ought to be looked at as well. That could uncover further 'bug's, and fixing them (adding support for numpy arrays) could easily be a lot more work than generalising a few if statements as in your fix.
Anyway, I have reproduced this (Python 3.11.4, Windows 11, x86, numpy==1.26.0, pyshp==2.3.1), and show the cause of the error below:
import numpy as np
import shapefile as shp
def f(convert = None, file_name = 'test_polygon_bug_261.shp'):
points = [[0,0], [1,0],[1,1]]
if convert is not None:
points = [convert(point) for point in points]
with shp.Writer(file_name, shp.POLYGON) as w:
w.field('name', 'C')
w.poly([points])
w.record('triangle')
f()
f(convert = np.array)
Equality and inequality on numpy arrays is evaluated element wise. The error in _shapeparts in:
if part[0] != part[-1]:
comes when numpy.array.__bool__ is called on an array of length 2 or more, e.g.:
>>> l = [0,0]
>>> np.array(l) == np.array(l)
array([ True, True])
>>> assert np.array(l) == np.array(l)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()