|  | 
| 15 | 15 | from __future__ import annotations | 
| 16 | 16 | 
 | 
| 17 | 17 | from bigframes import operations as ops | 
|  | 18 | +import bigframes.dtypes | 
| 18 | 19 | import bigframes.geopandas | 
| 19 | 20 | import bigframes.series | 
| 20 | 21 | 
 | 
| @@ -91,3 +92,122 @@ def st_area(series: bigframes.series.Series) -> bigframes.series.Series: | 
| 91 | 92 |     series = series._apply_unary_op(ops.geo_area_op) | 
| 92 | 93 |     series.name = None | 
| 93 | 94 |     return series | 
|  | 95 | + | 
|  | 96 | + | 
|  | 97 | +def st_difference( | 
|  | 98 | +    series: bigframes.series.Series, other: bigframes.series.Series | 
|  | 99 | +) -> bigframes.series.Series: | 
|  | 100 | +    """ | 
|  | 101 | +    Returns a GEOGRAPHY that represents the point set difference of | 
|  | 102 | +    `geography_1` and `geography_2`. Therefore, the result consists of the part | 
|  | 103 | +    of `geography_1` that doesn't intersect with `geography_2`. | 
|  | 104 | +
 | 
|  | 105 | +    If `geometry_1` is completely contained in `geometry_2`, then ST_DIFFERENCE | 
|  | 106 | +    returns an empty GEOGRAPHY. | 
|  | 107 | +
 | 
|  | 108 | +    ..note:: | 
|  | 109 | +        BigQuery's Geography functions, like `st_difference`, interpret the geometry | 
|  | 110 | +        data type as a point set on the Earth's surface. A point set is a set | 
|  | 111 | +        of points, lines, and polygons on the WGS84 reference spheroid, with | 
|  | 112 | +        geodesic edges. See: https://cloud.google.com/bigquery/docs/geospatial-data | 
|  | 113 | +
 | 
|  | 114 | +    **Examples:** | 
|  | 115 | +
 | 
|  | 116 | +        >>> import bigframes as bpd | 
|  | 117 | +        >>> import bigframes.bigquery as bbq | 
|  | 118 | +        >>> import bigframes.geopandas | 
|  | 119 | +        >>> from shapely.geometry import Polygon, LineString, Point | 
|  | 120 | +        >>> bpd.options.display.progress_bar = None | 
|  | 121 | +
 | 
|  | 122 | +    We can check two GeoSeries against each other, row by row. | 
|  | 123 | +
 | 
|  | 124 | +        >>> s1 = bigframes.geopandas.GeoSeries( | 
|  | 125 | +        ...    [ | 
|  | 126 | +        ...        Polygon([(0, 0), (2, 2), (0, 2)]), | 
|  | 127 | +        ...        Polygon([(0, 0), (2, 2), (0, 2)]), | 
|  | 128 | +        ...        LineString([(0, 0), (2, 2)]), | 
|  | 129 | +        ...        LineString([(2, 0), (0, 2)]), | 
|  | 130 | +        ...        Point(0, 1), | 
|  | 131 | +        ...    ], | 
|  | 132 | +        ... ) | 
|  | 133 | +        >>> s2 = bigframes.geopandas.GeoSeries( | 
|  | 134 | +        ...    [ | 
|  | 135 | +        ...        Polygon([(0, 0), (1, 1), (0, 1)]), | 
|  | 136 | +        ...        LineString([(1, 0), (1, 3)]), | 
|  | 137 | +        ...        LineString([(2, 0), (0, 2)]), | 
|  | 138 | +        ...        Point(1, 1), | 
|  | 139 | +        ...        Point(0, 1), | 
|  | 140 | +        ...    ], | 
|  | 141 | +        ...    index=range(1, 6), | 
|  | 142 | +        ... ) | 
|  | 143 | +
 | 
|  | 144 | +        >>> s1 | 
|  | 145 | +        0    POLYGON ((0 0, 2 2, 0 2, 0 0)) | 
|  | 146 | +        1    POLYGON ((0 0, 2 2, 0 2, 0 0)) | 
|  | 147 | +        2             LINESTRING (0 0, 2 2) | 
|  | 148 | +        3             LINESTRING (2 0, 0 2) | 
|  | 149 | +        4                       POINT (0 1) | 
|  | 150 | +        dtype: geometry | 
|  | 151 | +
 | 
|  | 152 | +        >>> s2 | 
|  | 153 | +        1    POLYGON ((0 0, 1 1, 0 1, 0 0)) | 
|  | 154 | +        2             LINESTRING (1 0, 1 3) | 
|  | 155 | +        3             LINESTRING (2 0, 0 2) | 
|  | 156 | +        4                       POINT (1 1) | 
|  | 157 | +        5                       POINT (0 1) | 
|  | 158 | +        dtype: geometry | 
|  | 159 | +
 | 
|  | 160 | +        >>> bbq.st_difference(s1, s2) | 
|  | 161 | +        0                                               None | 
|  | 162 | +        1    POLYGON ((0.99954 1, 2 2, 0 2, 0 1, 0.99954 1)) | 
|  | 163 | +        2                   LINESTRING (0 0, 1 1.00046, 2 2) | 
|  | 164 | +        3                           GEOMETRYCOLLECTION EMPTY | 
|  | 165 | +        4                                        POINT (0 1) | 
|  | 166 | +        5                                               None | 
|  | 167 | +        dtype: geometry | 
|  | 168 | +
 | 
|  | 169 | +    We can also check difference of single shapely geometries: | 
|  | 170 | +
 | 
|  | 171 | +        >>> sbq1 = bigframes.geopandas.GeoSeries( | 
|  | 172 | +        ...     [ | 
|  | 173 | +        ...         Polygon([(0, 0), (10, 0), (10, 10), (0, 0)]) | 
|  | 174 | +        ...     ] | 
|  | 175 | +        ... ) | 
|  | 176 | +        >>> sbq2 = bigframes.geopandas.GeoSeries( | 
|  | 177 | +        ...     [ | 
|  | 178 | +        ...         Polygon([(4, 2), (6, 2), (8, 6), (4, 2)]) | 
|  | 179 | +        ...     ] | 
|  | 180 | +        ... ) | 
|  | 181 | +
 | 
|  | 182 | +        >>> sbq1 | 
|  | 183 | +        0    POLYGON ((0 0, 10 0, 10 10, 0 0)) | 
|  | 184 | +        dtype: geometry | 
|  | 185 | +
 | 
|  | 186 | +        >>> sbq2 | 
|  | 187 | +        0    POLYGON ((4 2, 6 2, 8 6, 4 2)) | 
|  | 188 | +        dtype: geometry | 
|  | 189 | +
 | 
|  | 190 | +        >>> bbq.st_difference(sbq1, sbq2) | 
|  | 191 | +        0    POLYGON ((0 0, 10 0, 10 10, 0 0), (8 6, 6 2, 4... | 
|  | 192 | +        dtype: geometry | 
|  | 193 | +
 | 
|  | 194 | +    Additionally, we can check difference of a GeoSeries against a single shapely geometry: | 
|  | 195 | +
 | 
|  | 196 | +        >>> bbq.st_difference(s1, sbq2) | 
|  | 197 | +        0    POLYGON ((0 0, 2 2, 0 2, 0 0)) | 
|  | 198 | +        1                              None | 
|  | 199 | +        2                              None | 
|  | 200 | +        3                              None | 
|  | 201 | +        4                              None | 
|  | 202 | +        dtype: geometry | 
|  | 203 | +
 | 
|  | 204 | +    Args: | 
|  | 205 | +        other (bigframes.series.Series or geometric object): | 
|  | 206 | +            The GeoSeries (elementwise) or geometric object to find the difference to. | 
|  | 207 | +
 | 
|  | 208 | +    Returns: | 
|  | 209 | +        bigframes.series.Series: | 
|  | 210 | +            A GeoSeries of the points in each aligned geometry that are not | 
|  | 211 | +            in other. | 
|  | 212 | +    """ | 
|  | 213 | +    return series._apply_binary_op(other, ops.geo_st_difference_op) | 
0 commit comments