import math from shapely.geometry import Point, LineString, Polygon, MultiPolygon def create_rectangle(x, y, width, depth, angle): width_theta = math.radians(angle) width_x = width * math.cos(width_theta) width_y = width * math.sin(width_theta) depth_theta = math.radians(angle + 90) depth_x = depth * math.cos(depth_theta) depth_y = depth * math.sin(depth_theta) x0 = x y0 = y x1 = x + width_x y1 = y + width_y x2 = x + width_x + depth_x y2 = y + width_y + depth_y x3 = x + depth_x y3 = y + depth_y poly = Polygon([(x0, y0), (x1, y1), (x2, y2), (x3, y3)]) return poly def create_point(x, y, angle, distance): t = math.radians(angle) new_x = x + distance * math.cos(t) new_y = y + distance * math.sin(t) return Point(new_x, new_y) def find_angle(a, b, c): # c | / a # | / # | / # b |/ ba = (a.y - b.y, a.x - b.x) bc = (c.y - b.y, c.x - b.x) ang = math.degrees(math.atan2(bc[0], bc[1]) - math.atan2(ba[0], ba[1])) ang = ang + 360 if ang < 0 else ang return ang def xy(ring): r_xs, r_ys = list(), list() for pt in ring.coords: r_xs.append(pt[0]) r_ys.append(pt[1]) return r_xs, r_ys def linestring_list_xy(lines): l_xs, l_ys = list(), list() for line in lines: xs, ys = xy(line) l_xs.append(xs) l_ys.append(ys) return l_xs, l_ys def polygon_xy(poly): p_xs, p_ys = list(), list() x, y = xy(poly.exterior) p_xs.append(x) p_ys.append(y) for hole in poly.interiors: x, y = xy(hole) p_xs.append(x) p_ys.append(y) return p_xs, p_ys def multipolygon_xy(geom): mp_xs, mp_ys = list(), list() mp = MultiPolygon([geom]) if type(geom) == Polygon else geom for poly in mp.geoms: p_xs, p_ys = polygon_xy(poly) mp_xs.append(p_xs) mp_ys.append(p_ys) return mp_xs, mp_ys def multipolygon_list_xy(geoms): xs, ys = list(), list() for geom in geoms: mp_xs, mp_ys = multipolygon_xy(geom) xs.append(mp_xs) ys.append(mp_ys) return xs, ys def point_list_xy(points): x, y = list(), list() for pt in points: x.append(pt.x) y.append(pt.y) return x, y def create_slice_line(x, y, width, depth, angle, slices): buf_dist = 1 slices = round(slices) s = create_point(x, y, angle - 90, buf_dist) pts = list() for i in range(slices - 1): p0 = pts[(i * 2) - 1] if len(pts) else s p1 = create_point(p0.x, p0.y, angle, width / slices) p2 = create_point(p1.x, p1.y, angle + (-90 if i % 2 else 90), depth + buf_dist * 2) pts.extend([p1, p2]) l = LineString([(pt.x, pt.y) for pt in pts]) return l