|
16 | 16 | from rasterio.warp import transform_geom |
17 | 17 | from shapely.geometry import mapping, shape |
18 | 18 | from shapely.geometry.multipolygon import MultiPolygon |
19 | | -from shapely.geometry.polygon import Polygon |
| 19 | +from shapely.geometry.polygon import Polygon, orient |
20 | 20 |
|
21 | 21 | logger = logging.getLogger(__name__) |
22 | 22 |
|
@@ -49,11 +49,10 @@ def densify_by_factor( |
49 | 49 | points: Any = np.asarray(point_list) |
50 | 50 | densified_number = len(points) * factor |
51 | 51 | existing_indices = np.arange(0, densified_number, factor) |
52 | | - interp_indices = np.arange(existing_indices[-1]) |
| 52 | + interp_indices = np.arange(existing_indices[-1] + 1) |
53 | 53 | interp_x = np.interp(interp_indices, existing_indices, points[:, 0]) |
54 | 54 | interp_y = np.interp(interp_indices, existing_indices, points[:, 1]) |
55 | | - densified_points = [(x, y) for x, y in zip(interp_x, interp_y)] |
56 | | - return densified_points |
| 55 | + return [(x, y) for x, y in zip(interp_x, interp_y)] |
57 | 56 |
|
58 | 57 |
|
59 | 58 | def densify_by_distance( |
@@ -81,14 +80,17 @@ def densify_by_distance( |
81 | 80 | points: Any = np.asarray(point_list) |
82 | 81 | dxdy = points[1:, :] - points[:-1, :] |
83 | 82 | segment_lengths = np.sqrt(np.sum(np.square(dxdy), axis=1)) |
84 | | - total_length = np.sum(segment_lengths) |
85 | | - cum_segment_lengths = np.cumsum(segment_lengths) |
86 | | - cum_segment_lengths = np.insert(cum_segment_lengths, 0, [0]) |
87 | | - cum_interp_lengths = np.arange(0, total_length, distance) |
88 | | - cum_interp_lengths = np.append(cum_interp_lengths, [total_length]) |
89 | | - interp_x = np.interp(cum_interp_lengths, cum_segment_lengths, points[:, 0]) |
90 | | - interp_y = np.interp(cum_interp_lengths, cum_segment_lengths, points[:, 1]) |
91 | | - return [(x, y) for x, y in zip(interp_x, interp_y)] |
| 83 | + steps = segment_lengths / distance |
| 84 | + coordinate_steps = dxdy / steps.reshape(-1, 1) |
| 85 | + densified_points = np.empty((len(point_list) - 1,), dtype="O") |
| 86 | + for index in range(len(point_list) - 1): |
| 87 | + step = np.arange(steps[index]) |
| 88 | + densified_points[index] = ( |
| 89 | + np.array((step, step)).T * coordinate_steps[index] + points[index] |
| 90 | + ) |
| 91 | + final_point = points[-1].reshape(1, -1) |
| 92 | + densified_array = np.concatenate((*densified_points, final_point), axis=0) |
| 93 | + return [(float(row[0]), float(row[1])) for row in densified_array] |
92 | 94 |
|
93 | 95 |
|
94 | 96 | def reproject_polygon( |
@@ -290,7 +292,7 @@ def data_extent(self, mask: npt.NDArray[np.uint8]) -> Optional[Polygon]: |
290 | 292 | else: |
291 | 293 | polygon = MultiPolygon(data_polygons).convex_hull |
292 | 294 |
|
293 | | - return polygon |
| 295 | + return orient(polygon) |
294 | 296 |
|
295 | 297 | def densify_polygon(self, polygon: Polygon) -> Polygon: |
296 | 298 | """Adds vertices to the footprint polygon in the native CRS using |
@@ -343,8 +345,10 @@ def simplify_polygon(self, polygon: Polygon) -> Polygon: |
343 | 345 | Polygon: Reduced vertex polygon. |
344 | 346 | """ |
345 | 347 | if self.simplify_tolerance is not None: |
346 | | - return polygon.simplify( |
347 | | - tolerance=self.simplify_tolerance, preserve_topology=False |
| 348 | + return orient( |
| 349 | + polygon.simplify( |
| 350 | + tolerance=self.simplify_tolerance, preserve_topology=False |
| 351 | + ) |
348 | 352 | ) |
349 | 353 | return polygon |
350 | 354 |
|
|
0 commit comments