docs: def alpha_shape(points, alpha):
      """
      Compute the alpha shape (concave hull) of a set
      of points.
      @param points: Iterable container of points.
      @param alpha: alpha value to influence the
          gooeyness of the border. Smaller numbers
          don't fall inward as much as larger numbers.
          Too large, and you lose everything!
      """
      if len(points) < 4:
          # When you have a triangle, there is no sense
          # in computing an alpha shape.
          return geometry.MultiPoint(list(points)).convex_hull
  
      #coords = np.array([point.coords[0] for point in points])
  
      coords = np.array(points)
  
      print(coords)
  
      tri = Delaunay(coords)
      edges = set()
      edge_points = []
      # loop over triangles:
      # ia, ib, ic = indices of corner points of the
      # triangle
      for ia, ib, ic in tri.vertices:
          pa = coords[ia]
          pb = coords[ib]
          pc = coords[ic]
          # Lengths of sides of triangle
          a = math.sqrt((pa[0]-pb[0])**2 + (pa[1]-pb[1])**2)
          b = math.sqrt((pb[0]-pc[0])**2 + (pb[1]-pc[1])**2)
          c = math.sqrt((pc[0]-pa[0])**2 + (pc[1]-pa[1])**2)
          # Semiperimeter of triangle
          s = (a + b + c)/2.0
          # Area of triangle by Heron's formula
          area = math.sqrt(s*(s-a)*(s-b)*(s-c))
          circum_r = a*b*c/(4.0*area)
          # Here's the radius filter.
          #print circum_r
          if circum_r < 1.0/alpha:
              add_edge(edges, edge_points, coords, ia, ib)
              add_edge(edges, edge_points, coords, ib, ic)
              add_edge(edges, edge_points, coords, ic, ia)
      m = geometry.MultiLineString(edge_points)
      triangles = list(polygonize(m))
      return (cascaded_union(triangles), edge_points)
  
      print (cascaded_union(triangles), edge_points)