Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

feat: add bigframes.bigquery.st_area and suggest it from GeoSeries.area #1318

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 24 commits into from
Feb 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
936c4f2
feat: Add GeoSeries.area
arwas11 Jan 23, 2025
c835b5f
Merge remote-tracking branch 'origin/main' into b308738592-geopandas-…
arwas11 Jan 23, 2025
8d8eef3
fix formatting
arwas11 Jan 23, 2025
6331915
fix import error
arwas11 Jan 23, 2025
0cb819e
fix format and return type
arwas11 Jan 24, 2025
df075dd
update test
arwas11 Jan 24, 2025
52aa0a0
Merge branch 'main' into b308738592-geopandas-area
arwas11 Jan 24, 2025
d86e441
add type ignore flag
arwas11 Jan 24, 2025
2f542ad
Merge remote-tracking branch 'origin/b308738592-geopandas-area' into …
arwas11 Jan 24, 2025
eb0ba0b
Merge remote-tracking branch 'origin/main' into b308738592-geopandas-…
arwas11 Jan 27, 2025
e613b64
add and test st_area
arwas11 Feb 3, 2025
1549152
Merge branch 'main' into b308738592-geopandas-area
arwas11 Feb 3, 2025
381ea6c
Merge remote-tracking branch 'origin/main' into b308738592-geopandas-…
arwas11 Feb 3, 2025
77b1cea
update goseries notebook with area and st_area
arwas11 Feb 3, 2025
7dbf7e0
Merge remote-tracking branch 'origin/b308738592-geopandas-area' into …
arwas11 Feb 4, 2025
2b22d35
Merge remote-tracking branch 'origin/main' into b308738592-geopandas-…
arwas11 Feb 4, 2025
37533f8
ignore mypy error
arwas11 Feb 4, 2025
bbbcced
update the notebook
arwas11 Feb 4, 2025
5508dda
update the notebook
arwas11 Feb 4, 2025
11d0603
ignore exception in notebook
arwas11 Feb 4, 2025
d121a1a
update test data and add comment
arwas11 Feb 4, 2025
5245f24
Merge branch 'main' into b308738592-geopandas-area
arwas11 Feb 4, 2025
8530103
Update tests/system/small/bigquery/test_geo.py
tswast Feb 4, 2025
f288e4f
Update tests/system/small/bigquery/test_geo.py
tswast Feb 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions 3 bigframes/bigquery/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
unix_millis,
unix_seconds,
)
from bigframes.bigquery._operations.geo import st_area
from bigframes.bigquery._operations.json import (
json_extract,
json_extract_array,
Expand All @@ -45,6 +46,8 @@
"array_length",
"array_agg",
"array_to_string",
# geo ops
"st_area",
# json ops
"json_set",
"json_extract",
Expand Down
93 changes: 93 additions & 0 deletions 93 bigframes/bigquery/_operations/geo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import annotations

from bigframes import operations as ops
import bigframes.geopandas
import bigframes.series

"""
Search functions defined from
https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions
"""


def st_area(self) -> bigframes.series.Series:
"""
Returns the area in square meters covered by the polygons in the input
GEOGRAPHY.

If geography_expression is a point or a line, returns zero. If
geography_expression is a collection, returns the area of the polygons
in the collection; if the collection doesn't contain polygons, returns zero.


..note::
BigQuery's Geography functions, like `st_area`, interpet the geomtry
data type as a point set on the Earth's surface. A point set is a set
of points, lines, and polygons on the WGS84 reference spheroid, with
geodesic edges. See: https://cloud.google.com/bigquery/docs/geospatial-data


**Examples:**

>>> import bigframes.geopandas
>>> import bigframes.pandas as bpd
>>> import bigframes.bigquery as bbq
>>> from shapely.geometry import Polygon, LineString, Point
>>> bpd.options.display.progress_bar = None

>>> series = bigframes.geopandas.GeoSeries(
... [
... Polygon([(0.0, 0.0), (0.1, 0.1), (0.0, 0.1)]),
... Polygon([(0.10, 0.4), (0.9, 0.5), (0.10, 0.5)]),
... Polygon([(0.1, 0.1), (0.2, 0.1), (0.2, 0.2)]),
... LineString([(0, 0), (1, 1), (0, 1)]),
... Point(0, 1),
... ]
... )
>>> series
0 POLYGON ((0 0, 0.1 0.1, 0 0.1, 0 0))
1 POLYGON ((0.1 0.4, 0.9 0.5, 0.1 0.5, 0.1 0.4))
2 POLYGON ((0.1 0.1, 0.2 0.1, 0.2 0.2, 0.1 0.1))
3 LINESTRING (0 0, 1 1, 0 1)
4 POINT (0 1)
dtype: geometry

>>> bbq.st_area(series)
0 61821689.855985
1 494563347.88721
2 61821689.855841
3 0.0
4 0.0
dtype: Float64

Use `round()` to round the outputed areas to the neares ten millions

>>> bbq.st_area(series).round(-7)
0 60000000.0
1 490000000.0
2 60000000.0
3 0.0
4 0.0
dtype: Float64

Returns:
bigframes.pandas.Series:
Series of float representing the areas.
"""
series = self._apply_unary_op(ops.geo_area_op)
series.name = None
return series
5 changes: 5 additions & 0 deletions 5 bigframes/core/compile/scalar_op_compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -993,6 +993,11 @@ def geo_y_op_impl(x: ibis_types.Value):
return typing.cast(ibis_types.GeoSpatialValue, x).y()


@scalar_op_compiler.register_unary_op(ops.geo_area_op)
def geo_area_op_impl(x: ibis_types.Value):
return typing.cast(ibis_types.GeoSpatialValue, x).area()


# Parameterized ops
@scalar_op_compiler.register_unary_op(ops.StructFieldOp, pass_op=True)
def struct_field_op_impl(x: ibis_types.Value, op: ops.StructFieldOp):
Expand Down
27 changes: 27 additions & 0 deletions 27 bigframes/geopandas/geoseries.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# limitations under the License.
from __future__ import annotations

import bigframes_vendored.constants as constants
import bigframes_vendored.geopandas.geoseries as vendored_geoseries
import geopandas.array # type: ignore

Expand All @@ -39,3 +40,29 @@ def y(self) -> bigframes.series.Series:
series = self._apply_unary_op(ops.geo_y_op)
series.name = None
return series

# GeoSeries.area overrides Series.area with something totally different.
# Ignore this type error, as we are trying to be as close to geopandas as
# we can.
@property
def area(self, crs=None) -> bigframes.series.Series: # type: ignore
"""Returns a Series containing the area of each geometry in the GeoSeries
expressed in the units of the CRS.

Args:
crs (optional):
Coordinate Reference System of the geometry objects. Can be
anything accepted by pyproj.CRS.from_user_input(), such as an
authority string (eg “EPSG:4326”) or a WKT string.

Returns:
bigframes.pandas.Series:
Series of float representing the areas.

Raises:
NotImplementedError:
GeoSeries.area is not supported. Use bigframes.bigquery.st_area(series), insetead.
"""
raise NotImplementedError(
f"GeoSeries.area is not supported. Use bigframes.bigquery.st_area(series), instead. {constants.FEEDBACK_LINK}"
)
3 changes: 2 additions & 1 deletion 3 bigframes/operations/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
SqlScalarOp,
where_op,
)
from bigframes.operations.geo_ops import geo_x_op, geo_y_op
from bigframes.operations.geo_ops import geo_area_op, geo_x_op, geo_y_op
from bigframes.operations.json_ops import (
JSONExtract,
JSONExtractArray,
Expand Down Expand Up @@ -332,6 +332,7 @@
# Geo ops
"geo_x_op",
"geo_y_op",
"geo_area_op",
# Numpy ops mapping
"NUMPY_TO_BINOP",
"NUMPY_TO_OP",
Expand Down
7 changes: 7 additions & 0 deletions 7 bigframes/operations/geo_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,10 @@
dtypes.is_geo_like, dtypes.FLOAT_DTYPE, description="geo-like"
),
)

geo_area_op = base_ops.create_unary_op(
name="geo_area",
type_signature=op_typing.FixedOutputType(
dtypes.is_geo_like, dtypes.FLOAT_DTYPE, description="geo-like"
),
)
Loading
Morty Proxy This is a proxified and sanitized view of the page, visit original site.