File: multipolygon.py

package info (click to toggle)
python-shapely 2.1.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,528 kB
  • sloc: python: 18,648; ansic: 6,615; makefile: 88; sh: 62
file content (125 lines) | stat: -rw-r--r-- 3,955 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
"""Collections of polygons and related utilities."""

import shapely
from shapely.geometry import polygon
from shapely.geometry.base import BaseMultipartGeometry

__all__ = ["MultiPolygon"]


class MultiPolygon(BaseMultipartGeometry):
    """A collection of one or more Polygons.

    If component polygons overlap the collection is invalid and some
    operations on it may fail.

    Parameters
    ----------
    polygons : sequence
        A sequence of Polygons, or a sequence of (shell, holes) tuples
        where shell is the sequence representation of a linear ring
        (see LinearRing) and holes is a sequence of such linear rings.

    Attributes
    ----------
    geoms : sequence
        A sequence of `Polygon` instances

    Examples
    --------
    Construct a MultiPolygon from a sequence of coordinate tuples

    >>> from shapely import MultiPolygon, Polygon
    >>> ob = MultiPolygon([
    ...     (
    ...     ((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0)),
    ...     [((0.1,0.1), (0.1,0.2), (0.2,0.2), (0.2,0.1))]
    ...     )
    ... ])
    >>> len(ob.geoms)
    1
    >>> type(ob.geoms[0]) == Polygon
    True

    """

    __slots__ = []

    def __new__(self, polygons=None):
        """Create a new MultiPolygon geometry."""
        if polygons is None:
            # allow creation of empty multipolygons, to support unpickling
            # TODO better empty constructor
            return shapely.from_wkt("MULTIPOLYGON EMPTY")
        elif isinstance(polygons, MultiPolygon):
            return polygons

        polygons = getattr(polygons, "geoms", polygons)
        # remove None and empty polygons from list of Polygons
        polygons = [p for p in polygons if p]

        L = len(polygons)

        # Bail immediately if we have no input points.
        if L == 0:
            return shapely.from_wkt("MULTIPOLYGON EMPTY")

        # This function does not accept sequences of MultiPolygons: there is
        # no implicit flattening.
        if any(isinstance(p, MultiPolygon) for p in polygons):
            raise ValueError("Sequences of multi-polygons are not valid arguments")

        subs = []
        for i in range(L):
            ob = polygons[i]
            if not isinstance(ob, polygon.Polygon):
                shell = ob[0]
                if len(ob) > 1:
                    holes = ob[1]
                else:
                    holes = None
                p = polygon.Polygon(shell, holes)
            else:
                p = polygon.Polygon(ob)
            subs.append(p)

        return shapely.multipolygons(subs)

    @property
    def __geo_interface__(self):
        """Return a GeoJSON-like mapping of the MultiPolygon geometry."""
        allcoords = []
        for geom in self.geoms:
            coords = []
            coords.append(tuple(geom.exterior.coords))
            for hole in geom.interiors:
                coords.append(tuple(hole.coords))
            allcoords.append(tuple(coords))
        return {"type": "MultiPolygon", "coordinates": allcoords}

    def svg(self, scale_factor=1.0, fill_color=None, opacity=None):
        """Return group of SVG path elements for the MultiPolygon geometry.

        Parameters
        ----------
        scale_factor : float
            Multiplication factor for the SVG stroke-width.  Default is 1.
        fill_color : str, optional
            Hex string for fill color. Default is to use "#66cc99" if
            geometry is valid, and "#ff3333" if invalid.
        opacity : float
            Float number between 0 and 1 for color opacity. Default value is 0.6

        """
        if self.is_empty:
            return "<g />"
        if fill_color is None:
            fill_color = "#66cc99" if self.is_valid else "#ff3333"
        return (
            "<g>"
            + "".join(p.svg(scale_factor, fill_color, opacity) for p in self.geoms)
            + "</g>"
        )


shapely.lib.registry[6] = MultiPolygon