3

In Shapely I am getting an error:

"has no attribute geometry"

when I try to create a Polygon from a list with QgsPoint:

from shapely.geometry import Polygon

points = [<QgsPoint: PointZ (-1.96778375739159395 52.33374644648134222 0)>, <QgsPoint: PointZ (-1.49871941885997595 52.29018234320587766 0)>, <QgsPoint: PointZ (-1.5450353922021689 52.51784333059057275 0)>, <QgsPoint: PointZ (-2.00722642553756803 52.54952364559657241 0)>, <QgsPoint: PointZ (-1.96778375739159395 52.33374644648134222 0)>]

test_polygon = Polygon(points)

This was fine in QGIS 2 but not in QGIS 3. How to overcome the error?

1

1 Answer 1

2

I have seen your previous question, where I would like to extend @KadirŞahbaz's answer:

from shapely.geometry import Polygon

...
for steps in range(numVertices):
     pt = geom.vertexAt(steps)
     pt_x = geom.vertexAt(steps).x()
     pt_y = geom.vertexAt(steps).y()
     pt_z = geom.vertexAt(steps).z()
     points.append((pt_x, pt_y, pt_z))

polygon = Polygon(points)
print(polygon.geom_type)

As mentioned in the Shapely documentation for the Polygon class:

The Polygon constructor takes two positional parameters. The first is an ordered sequence of (x, y[, z]) point tuples and is treated exactly as in the LinearRing case. The second is an optional unordered sequence of ring-like sequences specifying the interior boundaries or “holes” of the feature.

Therefore, the points should look like:

  • a list with tuples:

     from shapely.geometry import Polygon
    
     points = [(0, 0), (1, 1), (1, 0)]
     polygon = Polygon(points)
    
     print(polygon.geom_type) #Polygon
    
  • or a list with lists:

     from shapely.geometry import Point, Polygon
    
     coords = [[0, 0], [1, 1], [1, 0]]
     polygon = Polygon(coords)
    
     print(polygon.geom_type) #Polygon
    
  • or a sequence of Point classes:

     from shapely.geometry import Point, Polygon
    
     coords = [Point(0, 0), Point(1, 1), Point(1, 0)]
     polygon = Polygon(coords)
    
     print(polygon.geom_type) #Polygon
    
  • or via creating a LinearRing class:

     from shapely.geometry import Polygon, LinearRing
    
     coords = [(0, 0), (1, 1), (1, 0)]
     ring = LinearRing(coords)
     polygon = Polygon(ring)
    
     print(polygon.geom_type) #Polygon
    

More information one can get after using the print(help(Polygon)):

Help on class Polygon in module shapely.geometry.polygon:

class Polygon(shapely.geometry.base.BaseGeometry)
 |  Polygon(shell=None, holes=None)
 |  
 |  A two-dimensional figure bounded by a linear ring
 |  
 |  A polygon has a non-zero area. It may have one or more negative-space
 |  "holes" which are also bounded by linear rings. If any rings cross each
 |  other, the feature is invalid and operations on it may fail.
 |  
 |  Attributes
 |  ----------
 |  exterior : LinearRing
 |      The ring which bounds the positive space of the polygon.
 |  interiors : sequence
 |      A sequence of rings which bound all existing holes.
 |  
 |  Method resolution order:
 |      Polygon
 |      shapely.geometry.base.BaseGeometry
 |      builtins.object
 |  
 |  Methods defined here:
 |  
 |  __eq__(self, other)
 |      Return self==value.
 |  
 |  __init__(self, shell=None, holes=None)
 |      Parameters
 |      ----------
 |      shell : sequence
 |          A sequence of (x, y [,z]) numeric coordinate pairs or triples.
 |          Also can be a sequence of Point objects.
 |      holes : sequence
 |          A sequence of objects which satisfy the same requirements as the
 |          shell parameters above
 |      
 |      Example
 |      -------
 |      Create a square polygon with no holes
 |      
 |        >>> coords = ((0., 0.), (0., 1.), (1., 1.), (1., 0.), (0., 0.))
 |        >>> polygon = Polygon(coords)
 |        >>> polygon.area
 |        1.0
 |  
 |  __ne__(self, other)
 |      Return self!=value.
 |  
 |  svg(self, scale_factor=1.0, fill_color=None)
 |      Returns SVG path element for the Polygon geometry.
 |      
 |      Parameters
 |      ==========
 |      scale_factor : float
 |          Multiplication factor for the SVG stroke-width.  Default is 1.
 |      fill_color : str, optional
 |          Hex string for fill color. Default is to use "#66cc99" if
 |          geometry is valid, and "#ff3333" if invalid.
 |  
 |  ----------------------------------------------------------------------
 |  Class methods defined here:
 |  
 |  from_bounds(xmin, ymin, xmax, ymax) from builtins.type
 |      Construct a `Polygon()` from spatial bounds.
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |  
 |  __array_interface__
 |      Provide the Numpy array protocol.
 |  
 |  __geo_interface__
 |      Dictionary representation of the geometry
 |  
 |  coords
 |      Access to geometry's coordinates (CoordinateSequence)
 |  
 |  ctypes
 |      Return ctypes buffer
 |  
 |  exterior
 |  
 |  interiors
 |  
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |  
 |  __hash__ = None
 |  
 |  ----------------------------------------------------------------------
 |  Methods inherited from shapely.geometry.base.BaseGeometry:
 |  
 |  __and__(self, other)
 |  
 |  __bool__(self)
 |  
 |  __del__(self)
 |  
 |  __nonzero__(self)
 |  
 |  __or__(self, other)
 |  
 |  __reduce__(self)
 |      Helper for pickle.
 |  
 |  __setstate__(self, state)
 |  
 |  __str__(self)
 |      Return str(self).
 |  
 |  __sub__(self, other)
 |  
 |  __xor__(self, other)
 |  
 |  almost_equals(self, other, decimal=6)
 |      Returns True if geometries are equal at all coordinates to a
 |      specified decimal place
 |      
 |      Refers to approximate coordinate equality, which requires coordinates be
 |      approximately equal and in the same order for all components of a geometry.
 |  
 |  buffer(self, distance, resolution=16, quadsegs=None, cap_style=1, join_style=1, mitre_limit=5.0, single_sided=False)
 |      Get a geometry that represents all points within a distance
 |      of this geometry.
 |      
 |      A positive distance produces a dilation, a negative distance an
 |      erosion. A very small or zero distance may sometimes be used to
 |      "tidy" a polygon.
 |      
 |      Parameters
 |      ----------
 |      distance : float
 |          The distance to buffer around the object.
 |      resolution : int, optional
 |          The resolution of the buffer around each vertex of the
 |          object.
 |      quadsegs : int, optional
 |          Sets the number of line segments used to approximate an
 |          angle fillet.  Note: the use of a `quadsegs` parameter is
 |          deprecated and will be gone from the next major release.
 |      cap_style : int, optional
 |          The styles of caps are: CAP_STYLE.round (1), CAP_STYLE.flat
 |          (2), and CAP_STYLE.square (3).
 |      join_style : int, optional
 |          The styles of joins between offset segments are:
 |          JOIN_STYLE.round (1), JOIN_STYLE.mitre (2), and
 |          JOIN_STYLE.bevel (3).
 |      mitre_limit : float, optional
 |          The mitre limit ratio is used for very sharp corners. The
 |          mitre ratio is the ratio of the distance from the corner to
 |          the end of the mitred offset corner. When two line segments
 |          meet at a sharp angle, a miter join will extend the original
 |          geometry. To prevent unreasonable geometry, the mitre limit
 |          allows controlling the maximum length of the join corner.
 |          Corners with a ratio which exceed the limit will be beveled.
 |      single_side : bool, optional
 |          The side used is determined by the sign of the buffer
 |          distance:
 |      
 |              a positive distance indicates the left-hand side
 |              a negative distance indicates the right-hand side
 |      
 |          The single-sided buffer of point geometries is the same as
 |          the regular buffer.  The End Cap Style for single-sided
 |          buffers is always ignored, and forced to the equivalent of
 |          CAP_FLAT.
 |      
 |      Returns
 |      -------
 |      Geometry
 |      
 |      Notes
 |      -----
 |      The return value is a strictly two-dimensional geometry. All
 |      Z coordinates of the original geometry will be ignored.
 |      
 |      Examples
 |      --------
 |      >>> from shapely.wkt import loads
 |      >>> g = loads('POINT (0.0 0.0)')
 |      >>> g.buffer(1.0).area        # 16-gon approx of a unit radius circle
 |      3.1365484905459389
 |      >>> g.buffer(1.0, 128).area   # 128-gon approximation
 |      3.1415138011443009
 |      >>> g.buffer(1.0, 3).area     # triangle approximation
 |      3.0
 |      >>> list(g.buffer(1.0, cap_style=CAP_STYLE.square).exterior.coords)
 |      [(1.0, 1.0), (1.0, -1.0), (-1.0, -1.0), (-1.0, 1.0), (1.0, 1.0)]
 |      >>> g.buffer(1.0, cap_style=CAP_STYLE.square).area
 |      4.0
 |  
 |  contains(self, other)
 |      Returns True if the geometry contains the other, else False
 |  
 |  covers(self, other)
 |      Returns True if the geometry covers the other, else False
 |  
 |  crosses(self, other)
 |      Returns True if the geometries cross, else False
 |  
 |  difference(self, other)
 |      Returns the difference of the geometries
 |  
 |  disjoint(self, other)
 |      Returns True if geometries are disjoint, else False
 |  
 |  distance(self, other)
 |      Unitless distance to other geometry (float)
 |  
 |  empty(self, val=51640517376)
 |  
 |  equals(self, other)
 |      Returns True if geometries are equal, else False
 |      
 |      Refers to point-set equality (or topological equality), and is equivalent to
 |      (self.within(other) & self.contains(other))
 |  
 |  equals_exact(self, other, tolerance)
 |      Returns True if geometries are equal to within a specified
 |      tolerance
 |      
 |      Refers to coordinate equality, which requires coordinates to be equal
 |      and in the same order for all components of a geometry
 |  
 |  geometryType(self)
 |  
 |  hausdorff_distance(self, other)
 |      Unitless hausdorff distance to other geometry (float)
 |  
 |  interpolate(self, distance, normalized=False)
 |      Return a point at the specified distance along a linear geometry
 |      
 |      Negative length values are taken as measured in the reverse
 |      direction from the end of the geometry. Out-of-range index
 |      values are handled by clamping them to the valid range of values.
 |      If the normalized arg is True, the distance will be interpreted as a
 |      fraction of the geometry's length.
 |  
 |  intersection(self, other)
 |      Returns the intersection of the geometries
 |  
 |  intersects(self, other)
 |      Returns True if geometries intersect, else False
 |  
 |  overlaps(self, other)
 |      Returns True if geometries overlap, else False
 |  
 |  project(self, other, normalized=False)
 |      Returns the distance along this geometry to a point nearest the
 |      specified point
 |      
 |      If the normalized arg is True, return the distance normalized to the
 |      length of the linear geometry.
 |  
 |  relate(self, other)
 |      Returns the DE-9IM intersection matrix for the two geometries
 |      (string)
 |  
 |  relate_pattern(self, other, pattern)
 |      Returns True if the DE-9IM string code for the relationship between
 |      the geometries satisfies the pattern, else False
 |  
 |  representative_point(self)
 |      Returns a point guaranteed to be within the object, cheaply.
 |  
 |  simplify(self, tolerance, preserve_topology=True)
 |      Returns a simplified geometry produced by the Douglas-Peucker
 |      algorithm
 |      
 |      Coordinates of the simplified geometry will be no more than the
 |      tolerance distance from the original. Unless the topology preserving
 |      option is used, the algorithm may produce self-intersecting or
 |      otherwise invalid geometries.
 |  
 |  symmetric_difference(self, other)
 |      Returns the symmetric difference of the geometries
 |      (Shapely geometry)
 |  
 |  to_wkb(self)
 |  
 |  to_wkt(self)
 |  
 |  touches(self, other)
 |      Returns True if geometries touch, else False
 |  
 |  union(self, other)
 |      Returns the union of the geometries (Shapely geometry)
 |  
 |  within(self, other)
 |      Returns True if geometry is within the other, else False
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors inherited from shapely.geometry.base.BaseGeometry:
 |  
 |  __dict__
 |      dictionary for instance variables (if defined)
 |  
 |  __weakref__
 |      list of weak references to the object (if defined)
 |  
 |  area
 |      Unitless area of the geometry (float)
 |  
 |  array_interface_base
 |  
 |  boundary
 |      Returns a lower dimension geometry that bounds the object
 |      
 |      The boundary of a polygon is a line, the boundary of a line is a
 |      collection of points. The boundary of a point is an empty (null)
 |      collection.
 |  
 |  bounds
 |      Returns minimum bounding region (minx, miny, maxx, maxy)
 |  
 |  centroid
 |      Returns the geometric center of the object
 |  
 |  convex_hull
 |      Imagine an elastic band stretched around the geometry: that's a
 |      convex hull, more or less
 |      
 |      The convex hull of a three member multipoint, for example, is a
 |      triangular polygon.
 |  
 |  envelope
 |      A figure that envelopes the geometry
 |  
 |  geom_type
 |      Name of the geometry's type, such as 'Point'
 |  
 |  has_z
 |      True if the geometry's coordinate sequence(s) have z values (are
 |      3-dimensional)
 |  
 |  is_closed
 |      True if the geometry is closed, else False
 |      
 |      Applicable only to 1-D geometries.
 |  
 |  is_empty
 |      True if the set of points in this geometry is empty, else False
 |  
 |  is_ring
 |      True if the geometry is a closed ring, else False
 |  
 |  is_simple
 |      True if the geometry is simple, meaning that any self-intersections
 |      are only at boundary points, else False
 |  
 |  is_valid
 |      True if the geometry is valid (definition depends on sub-class),
 |      else False
 |  
 |  length
 |      Unitless length of the geometry (float)
 |  
 |  minimum_clearance
 |      Unitless distance by which a node could be moved to produce an invalid geometry (float)
 |  
 |  minimum_rotated_rectangle
 |      Returns the general minimum bounding rectangle of
 |      the geometry. Can possibly be rotated. If the convex hull
 |      of the object is a degenerate (line or point) this same degenerate
 |      is returned.
 |  
 |  type
 |  
 |  wkb
 |      WKB representation of the geometry
 |  
 |  wkb_hex
 |      WKB hex representation of the geometry
 |  
 |  wkt
 |      WKT representation of the geometry
 |  
 |  xy
 |      Separate arrays of X and Y coordinate values
 |  
 |  ----------------------------------------------------------------------
 |  Data and other attributes inherited from shapely.geometry.base.BaseGeometry:
 |  
 |  __geom__ = 51640517376
 |  
 |  __p__ = None
 |  
 |  impl = <GEOSImpl object: GEOS C API version (1, 10, 0)>
4
  • points=[<QgsPoint: PointZ (-1.96778375739159395 52.33374644648134222 0)>, <QgsPoint: PointZ (-1.49871941885997595 52.29018234320587766 0)>, <QgsPoint: PointZ (-1.5450353922021689 52.51784333059057275 0)>, <QgsPoint: PointZ (-2.00722642553756803 52.54952364559657241 0)>, <QgsPoint: PointZ (-1.96778375739159395 52.33374644648134222 0)>]
    – paulk
    May 5 at 19:28
  • problem appears to bevertex=geom.vertexAt(steps)
    – paulk
    May 6 at 8:48
  • it's producing the above instead of points=[(-1.96778,52.3337), (-1.49872,52.2902), (-1.54504,52.5178), (-2.00723,52.5495), (-1.96778,52.3337)] which us what QGIS2 produced
    – paulk
    May 6 at 8:53
  • Can you share your original data with me?
    – Taras
    May 6 at 8:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.