Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

not possible to create shapely object from wkt #463

Closed
pythonfun0 opened this issue Feb 6, 2017 · 7 comments
Closed

not possible to create shapely object from wkt #463

pythonfun0 opened this issue Feb 6, 2017 · 7 comments

Comments

@pythonfun0
Copy link

pythonfun0 commented Feb 6, 2017

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()
@pythonfun0 pythonfun0 changed the title not possible to creating spahley object from wkt not possible to creating shapely object from wkt Feb 6, 2017
@pythonfun0 pythonfun0 changed the title not possible to creating shapely object from wkt not possible to create shapely object from wkt Feb 6, 2017
@snorfalorpagus
Copy link
Member

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

@pythonfun0
Copy link
Author

pythonfun0 commented Feb 6, 2017

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

@geowurster
Copy link
Contributor

@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.

@pythonfun0
Copy link
Author

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!

@pythonfun0
Copy link
Author

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!

@snorfalorpagus
Copy link
Member

@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.

@pythonfun0
Copy link
Author

I've already get it, sorry I read absently your answers. A list of list of coordinates works perfectly.
Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants