Environment: Win10 64 bit
Version:
>>> shapely.__version__
'1.6a1'
Creating shapely object from wkt is working in case of point and linestring
from shapely.geometry import asShape
>>> asShape({'type': 'Point', 'coordinates': (0.0, 0.0)}).buffer(1.0).area
3.1365484905459384
>>> asShape({'type': "LineString", "coordinates": [(-1,0),(0,0)]}).buffer(1.0).area
5.13654849054594
but in case of polygon it fails. The object is seemingly created,
>>> asShape({'type': "Polygon", "coordinates": [(0,0), (0,1), (1,1),(1,0),(0,0)]})
<shapely.geometry.polygon.PolygonAdapter object at 0x00000251C2CA7710>
however calling any methods throwing exceptions
>>> asShape({'type': "Polygon", "coordinates": [(0,0), (0,1), (1,1),(1,0),(0,0)]}).area
Traceback (most recent call last):
File "C:\Anaconda3\lib\site-packages\shapely\geometry\polygon.py", line 407, in geos_linearring_from_py
array = ob.__array_interface__
AttributeError: 'tuple' object has no attribute '__array_interface__'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<pyshell#66>", line 1, in <module>
asShape({'type': "Polygon", "coordinates": [(0,0), (0,1), (1,1),(1,0),(0,0)]}).area()
File "C:\Anaconda3\lib\site-packages\shapely\geometry\base.py", line 431, in area
return self.impl['area'](self)
File "C:\Anaconda3\lib\site-packages\shapely\topology.py", line 55, in __call__
self._validate(this)
File "C:\Anaconda3\lib\site-packages\shapely\topology.py", line 17, in _validate
if ob is None or ob._geom is None:
File "C:\Anaconda3\lib\site-packages\shapely\geometry\proxy.py", line 49, in _geom
self.__geom__, n = self.factory(self.context[0], self.context[1])
File "C:\Anaconda3\lib\site-packages\shapely\geometry\polygon.py", line 526, in geos_polygon_from_py
ret = geos_linearring_from_py(shell)
File "C:\Anaconda3\lib\site-packages\shapely\geometry\polygon.py", line 468, in geos_linearring_from_py
n = len(ob[0])
TypeError: object of type 'int' has no len()
These examples are not using WKT. http://toblerity.org/shapely/manual.html#well-known-formats
They are using the __geo_interface__ representation of the geometry, which is fine.
The reason your polygon is failing is because it's not valid. Polygon coordinate sequences should be a list of lists of coordinates, not a list of coordinates as you have. This is because a polygon is composed of multiple linear rings - an exterior ring, and optional multiple interior rings.
The following code works. Note the additional brackets in the coordinates.
>>> polygon = asShape({'type': "Polygon", "coordinates": [[(0,0), (0,1), (1,1),(1,0),(0,0)]]})
>>> polygon.is_valid
Also note that if you're not using numpy arrays for the coordinates you could just as well use shape()
instead of asShape()
. In this case the error is raised immediately, rather than when you try to access the data. http://toblerity.org/shapely/shapely.geometry.html#shapely.geometry.asShape
Okey, I misspelled the list, but either the correct form does not work:
polygon = asShape({'type': "Polygon", "coordinates": [(0,0), (0,1), (1,1),(1,0),(0,0)]})
>>> polygon.area
Traceback (most recent call last):
File "C:\Anaconda3\lib\site-packages\shapely\geometry\polygon.py", line 407, in geos_linearring_from_py
array = ob.__array_interface__
AttributeError: 'tuple' object has no attribute '__array_interface__'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<pyshell#8>", line 1, in <module>
polygon.area
File "C:\Anaconda3\lib\site-packages\shapely\geometry\base.py", line 431, in area
return self.impl['area'](self)
File "C:\Anaconda3\lib\site-packages\shapely\topology.py", line 55, in __call__
self._validate(this)
File "C:\Anaconda3\lib\site-packages\shapely\topology.py", line 17, in _validate
if ob is None or ob._geom is None:
File "C:\Anaconda3\lib\site-packages\shapely\geometry\proxy.py", line 49, in _geom
self.__geom__, n = self.factory(self.context[0], self.context[1])
File "C:\Anaconda3\lib\site-packages\shapely\geometry\polygon.py", line 526, in geos_polygon_from_py
ret = geos_linearring_from_py(shell)
File "C:\Anaconda3\lib\site-packages\shapely\geometry\polygon.py", line 468, in geos_linearring_from_py
n = len(ob[0])
TypeError: object of type 'int' has no len()
even if I use numpy array:
arr = numpy.array([(0,0), (0,1), (1,1),(1,0),(0,0)])
ss = asShape({'type': "Polygon", "coordinates": arr})
>>> ss.area
Traceback (most recent call last):
File "<pyshell#16>", line 1, in <module>
ss.area
File "C:\Anaconda3\lib\site-packages\shapely\geometry\base.py", line 431, in area
return self.impl['area'](self)
File "C:\Anaconda3\lib\site-packages\shapely\topology.py", line 55, in __call__
self._validate(this)
File "C:\Anaconda3\lib\site-packages\shapely\topology.py", line 17, in _validate
if ob is None or ob._geom is None:
File "C:\Anaconda3\lib\site-packages\shapely\geometry\proxy.py", line 49, in _geom
self.__geom__, n = self.factory(self.context[0], self.context[1])
File "C:\Anaconda3\lib\site-packages\shapely\geometry\polygon.py", line 526, in geos_polygon_from_py
ret = geos_linearring_from_py(shell)
File "C:\Anaconda3\lib\site-packages\shapely\geometry\polygon.py", line 408, in geos_linearring_from_py
assert len(array['shape']) == 2
AssertionError
@pythonfun0 Your polygon definition is not quite right. Try this:
polygon = shape({'type': "Polygon", "coordinates": [[(0,0), (0,1), (1,1),(1,0),(0,0)]]})
Note the additional set of brackets around the coordinates. The structure for a GeoJSON Polygon
is:
For type "Polygon", the "coordinates" member must be an array of LinearRing coordinate arrays. For Polygons with multiple rings, the first must be the exterior ring and any others must be interior rings or holes.
In other words:
{
"type": "Polygon",
"coordinates": [
[<outer ring: (x, y), (x, y), ...>],
[<hole 1 ring: (x, y), (x, y), ...>],
[<hole 2 ring: (x, y), (x, y), ...>],
]
}
but you don't have any holes, so you need:
{
"type": "Polygon",
"coordinates": [
[<outer ring: (x, y), (x, y), ...>],
]
}
Your LineString
example works because the outer ring alone _is_ a valid LineString
, but it is not a valid Polygon
on its own unless it is nested properly.
If you read carefully my later comment, I wrote that it is not a nested list, I misspelled it!
So, once again I tried to crate polygon from wkt this way:
polygon = asShape({'type': "Polygon", "coordinates": [(0,0), (0,1), (1,1),(1,0),(0,0)]})
I don't want to create any nested polygon object!
Please, paste a real working code example, if you can have it!
Thanks!
If you read carefully my later comment, I wrote that it is not a nested list, I misspelled it!
So, once again I tried to crate polygon from wkt this way:
polygon = asShape({'type': "Polygon", "coordinates": [(0,0), (0,1), (1,1),(1,0),(0,0)]})
it does not work with square brackets
polygon = asShape({'type':'Polygon', 'coordinates':[[0,0],[0,1],[1,1],[1,0]]})
I don't want to create any nested polygon object!
Please, paste a real working code example, if you can have it!
Thanks!
@pythonfun0 You're not seeing what we're trying to point out.
You're typing this:
polygon = asShape({'type': "Polygon", "coordinates": [(0,0), (0,1), (1,1), (1,0), (0,0)]})
You should be typing this:
polygon = asShape({'type': "Polygon", "coordinates": [[(0,0), (0,1), (1,1), (1,0), (0,0)]]})
Even if your polygon only has an exterior ring and no interior rings, you still need to pass a nested list.
I've already get it, sorry I read absently your answers. A list of list of coordinates works perfectly.
Thank you!
Most helpful comment
These examples are not using WKT. http://toblerity.org/shapely/manual.html#well-known-formats
They are using the __geo_interface__ representation of the geometry, which is fine.
The reason your polygon is failing is because it's not valid. Polygon coordinate sequences should be a list of lists of coordinates, not a list of coordinates as you have. This is because a polygon is composed of multiple linear rings - an exterior ring, and optional multiple interior rings.
The following code works. Note the additional brackets in the coordinates.
Also note that if you're not using numpy arrays for the coordinates you could just as well use
shape()
instead ofasShape()
. In this case the error is raised immediately, rather than when you try to access the data. http://toblerity.org/shapely/shapely.geometry.html#shapely.geometry.asShape