Exemple #1
0
def assert_shapes_mostly_equal(shape1: BaseGeometry, shape2: BaseGeometry,
                               threshold: float):
    __tracebackhide__ = operator.methodcaller("errisinstance", AssertionError)

    # Check area first, as it's a nicer error message when they're wildly different.
    assert shape1.area == pytest.approx(
        shape2.area, abs=threshold), "Shapes have different areas"

    s1 = shape1.simplify(tolerance=threshold)
    s2 = shape2.simplify(tolerance=threshold)
    assert (s1 - s2).area < threshold, f"{s1} is not mostly equal to {s2}"
Exemple #2
0
 def decompose(self, geometry: BaseGeometry) -> List[LineString]:
     geometry = geometry.simplify(self._simplify_distance)
     if isinstance(geometry, Polygon):
         return self.decompose_polygon(polygon=geometry)
     elif isinstance(geometry, MultiPolygon):
         lines_list: List[List[LineString]] = [
             self.decompose_polygon(polygon=sub_polygon)
             for sub_polygon in list(geometry)
         ]
         return list(chain.from_iterable(lines_list))
     elif isinstance(geometry, LinearRing):
         return self.decompose_linearRing(ring=geometry)
     elif isinstance(geometry, LineString):
         return self.decompose_lineString(lineString=geometry)
     elif isinstance(geometry, MultiLineString):
         lines_list: List[List[LineString]] = [
             self.decompose_lineString(lineString=sub_lineString)
             for sub_lineString in list(geometry)
         ]
         return list(chain.from_iterable(lines_list))
     elif isinstance(geometry, GeometryCollection):
         lines_list: List[List[LineString]] = [
             self.decompose(geometry=sub_geometry)
             for sub_geometry in list(geometry)
         ]
         return list(chain.from_iterable(lines_list))
     else:
         return []
Exemple #3
0
def interpolate(geometry: BaseGeometry,
                gap: float,
                simplify_distance: float = 1e-6) -> BaseGeometry:
    def interpolate_coords(coords):
        new_coords: List[Tuple[float, float]] = []
        for i in range(len(coords) - 2):
            new_coords.extend(
                interpolate_coords_by_len(coords[i],
                                          coords[i + 1],
                                          gap,
                                          result_include_coord2=False))
        new_coords.extend(
            interpolate_coords_by_len(coords[-2],
                                      coords[-1],
                                      gap,
                                      result_include_coord2=True))
        return new_coords

    if isinstance(geometry, (Point, MultiPoint)):
        return geometry
    elif isinstance(geometry, (Polygon, LineString, LinearRing)):
        geometry_simplified = geometry.simplify(simplify_distance)
        if isinstance(geometry, Polygon):
            exterior_coords = list(geometry_simplified.exterior.coords)
            interior_coords_list = [
                list(interior.coords)
                for interior in geometry_simplified.interiors
            ]
            interpolated_exterior = interpolate_coords(exterior_coords)
            interpolated_interiors = [
                interpolate_coords(interior_coords)
                for interior_coords in interior_coords_list
            ]
            return Polygon(shell=interpolated_exterior,
                           holes=interpolated_interiors)
        else:  # LineString or LinearRing
            coords = list(geometry_simplified.coords)
            return type(geometry)(interpolate_coords(coords))
    elif isinstance(geometry,
                    (MultiPolygon, MultiLineString, GeometryCollection)):
        geoms = list(geometry)
        interpolated_geoms = [interpolate(geom, gap) for geom in geoms]
        return type(geometry)(interpolated_geoms)

    return geometry  # return origin geometry if not match any type