Recursively convert a single geometry to a sequence of tagged points.
(geometry: Geometry, recursion_level=0)
| 63 | |
| 64 | |
| 65 | def flatten_single(geometry: Geometry, recursion_level=0) -> TaggedPointSequence: |
| 66 | """Recursively convert a single geometry to a sequence of tagged points.""" |
| 67 | indent = " " * recursion_level |
| 68 | logger.debug(indent + "Converting %s to tagged points.", geometry.geom_type) |
| 69 | |
| 70 | if isinstance(geometry, Point): |
| 71 | yield geometry.coords[0], () |
| 72 | elif isinstance(geometry, LineString): |
| 73 | yield from wrap_bare(geometry.coords, PointTag.LINESTRING_BEGIN) |
| 74 | elif isinstance(geometry, Polygon): |
| 75 | shell = wrap_bare(geometry.exterior.coords, PointTag.SHELL_BEGIN) |
| 76 | holes = itertools.chain.from_iterable( |
| 77 | wrap_bare(h.coords, PointTag.HOLE_BEGIN) for h in geometry.interiors |
| 78 | ) |
| 79 | points = itertools.chain(shell, holes) |
| 80 | yield from wrap_tagged(points, PointTag.POLYGON_BEGIN) |
| 81 | elif isinstance(geometry, MultiPoint): |
| 82 | points = itertools.chain.from_iterable( |
| 83 | flatten_single(g, recursion_level + 1) for g in geometry.geoms |
| 84 | ) |
| 85 | yield from wrap_tagged(points, PointTag.MULTIPOINT_BEGIN) |
| 86 | elif isinstance(geometry, MultiLineString): |
| 87 | points = itertools.chain.from_iterable( |
| 88 | flatten_single(g, recursion_level + 1) for g in geometry.geoms |
| 89 | ) |
| 90 | yield from wrap_tagged(points, PointTag.MULTILINESTRING_BEGIN) |
| 91 | elif isinstance(geometry, MultiPolygon): |
| 92 | points = itertools.chain.from_iterable( |
| 93 | flatten_single(g, recursion_level + 1) for g in geometry.geoms |
| 94 | ) |
| 95 | yield from wrap_tagged(points, PointTag.MULTIPOLYGON_BEGIN) |
| 96 | elif isinstance(geometry, GeometryCollection): |
| 97 | points = itertools.chain.from_iterable( |
| 98 | flatten_single(g, recursion_level + 1) for g in geometry.geoms |
| 99 | ) |
| 100 | yield from wrap_tagged(points, PointTag.COLLECTION_BEGIN) |
| 101 | else: |
| 102 | logger.error(indent + "Unsupported geometry type '%s'", type(geometry)) |
| 103 | |
| 104 | |
| 105 | def wrap_bare(coords: Iterable[Tuple[float]], begin_tag: PointTag) -> TaggedPointSequence: |