From 936c4f2e14914c826eb0146680f6201e798bef44 Mon Sep 17 00:00:00 2001 From: Arwa Date: Thu, 23 Jan 2025 13:33:38 -0600 Subject: [PATCH 01/15] feat: Add GeoSeries.area --- bigframes/core/compile/scalar_op_compiler.py | 4 ++++ bigframes/geopandas/geoseries.py | 7 +++++++ bigframes/operations/__init__.py | 3 ++- bigframes/operations/geo_ops.py | 7 +++++++ .../system/small/geopandas/test_geoseries.py | 18 ++++++++++++++++ .../bigframes_vendored/geopandas/geoseries.py | 21 +++++++++++++++++-- 6 files changed, 57 insertions(+), 3 deletions(-) diff --git a/bigframes/core/compile/scalar_op_compiler.py b/bigframes/core/compile/scalar_op_compiler.py index 3f4400d6ce..5e5c8eba15 100644 --- a/bigframes/core/compile/scalar_op_compiler.py +++ b/bigframes/core/compile/scalar_op_compiler.py @@ -977,6 +977,10 @@ def geo_x_op_impl(x: ibis_types.Value): 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) diff --git a/bigframes/geopandas/geoseries.py b/bigframes/geopandas/geoseries.py index 7a5b24f413..6b2a9d24cf 100644 --- a/bigframes/geopandas/geoseries.py +++ b/bigframes/geopandas/geoseries.py @@ -16,6 +16,7 @@ import bigframes_vendored.geopandas.geoseries as vendored_geoseries import geopandas.array # type: ignore +import bigframes_vendored.constants as constants import bigframes.operations as ops import bigframes.series @@ -39,3 +40,9 @@ def y(self) -> bigframes.series.Series: series = self._apply_unary_op(ops.geo_y_op) series.name = None return series + + @property + def area(self, crs=None) -> bigframes.dataFrame.DataFrame: + raise NotImplementedError( + f"GeoSeries.area is not supported. Use bigframes.bigquery.st_area(series), instead. {constants.FEEDBACK_LINK}" + ) diff --git a/bigframes/operations/__init__.py b/bigframes/operations/__init__.py index 114b7f56bc..8fd448b978 100644 --- a/bigframes/operations/__init__.py +++ b/bigframes/operations/__init__.py @@ -80,7 +80,7 @@ RowKey, where_op, ) -from bigframes.operations.geo_ops import geo_x_op, geo_y_op +from bigframes.operations.geo_ops import geo_x_op, geo_y_op, geo_area_op from bigframes.operations.json_ops import ( JSONExtract, JSONExtractArray, @@ -319,6 +319,7 @@ # Geo ops "geo_x_op", "geo_y_op", + "geo_area_op", # Numpy ops mapping "NUMPY_TO_BINOP", "NUMPY_TO_OP", diff --git a/bigframes/operations/geo_ops.py b/bigframes/operations/geo_ops.py index 73e7e89197..bc14fa611b 100644 --- a/bigframes/operations/geo_ops.py +++ b/bigframes/operations/geo_ops.py @@ -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" + ), +) diff --git a/tests/system/small/geopandas/test_geoseries.py b/tests/system/small/geopandas/test_geoseries.py index a30460d461..0d2b6f0c2a 100644 --- a/tests/system/small/geopandas/test_geoseries.py +++ b/tests/system/small/geopandas/test_geoseries.py @@ -16,6 +16,7 @@ import google.api_core.exceptions import pandas as pd import pytest +from shapely.geometry import Polygon, LineString, Point import bigframes.geopandas import bigframes.series @@ -61,3 +62,20 @@ def test_geo_y(urban_areas_dfs): pd_result.astype(pd.Float64Dtype()), bf_result, ) + + +def test_geo_area_not_supported(urban_areas_dfs): + series = bigframes.pandas.Series( + [ + Polygon([(0, 0), (1, 1), (0, 1)]), + Polygon([(10, 0), (10, 5), (0, 0)]), + Polygon([(0, 0), (2, 2), (2, 0)]), + LineString([(0, 0), (1, 1), (0, 1)]), + Point(0, 1) + ], dtype=geopandas.array.GeometryDtype() + ) + bf_series: bigframes.geopandas.GeoSeries = series.geo + with pytest.raises(NotImplementedError): + bf_series.area() + + diff --git a/third_party/bigframes_vendored/geopandas/geoseries.py b/third_party/bigframes_vendored/geopandas/geoseries.py index 2ad35ed852..88a5044edf 100644 --- a/third_party/bigframes_vendored/geopandas/geoseries.py +++ b/third_party/bigframes_vendored/geopandas/geoseries.py @@ -58,7 +58,7 @@ def x(self) -> bigframes.series.Series: dtype: Float64 Returns: - bigframes.series.Series: + bigframes.pandas.Series: Return the x location (longitude) of point geometries. """ raise NotImplementedError(constants.ABSTRACT_METHOD_ERROR_MESSAGE) @@ -85,7 +85,24 @@ def y(self) -> bigframes.series.Series: dtype: Float64 Returns: - bigframes.series.Series: + bigframes.pandas.Series: Return the y location (latitude) of point geometries. """ raise NotImplementedError(constants.ABSTRACT_METHOD_ERROR_MESSAGE) + + @property + def area(self, crs=None) -> bigframes.series.Series: + """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: + float: + Series of float representing the areas. + """ + raise NotImplementedError(constants.ABSTRACT_METHOD_ERROR_MESSAGE) From 8d8eef34c410e4e3045720603cbfde5a66391567 Mon Sep 17 00:00:00 2001 From: Arwa Date: Thu, 23 Jan 2025 13:45:13 -0600 Subject: [PATCH 02/15] fix formatting --- bigframes/core/compile/scalar_op_compiler.py | 1 + bigframes/geopandas/geoseries.py | 6 ++-- bigframes/operations/__init__.py | 2 +- .../system/small/geopandas/test_geoseries.py | 29 +++++++++---------- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/bigframes/core/compile/scalar_op_compiler.py b/bigframes/core/compile/scalar_op_compiler.py index 9fe0b7a495..7a53259ccd 100644 --- a/bigframes/core/compile/scalar_op_compiler.py +++ b/bigframes/core/compile/scalar_op_compiler.py @@ -992,6 +992,7 @@ def geo_x_op_impl(x: ibis_types.Value): 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() diff --git a/bigframes/geopandas/geoseries.py b/bigframes/geopandas/geoseries.py index 6b2a9d24cf..848e0d7ef0 100644 --- a/bigframes/geopandas/geoseries.py +++ b/bigframes/geopandas/geoseries.py @@ -13,10 +13,10 @@ # 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 -import bigframes_vendored.constants as constants import bigframes.operations as ops import bigframes.series @@ -44,5 +44,5 @@ def y(self) -> bigframes.series.Series: @property def area(self, crs=None) -> bigframes.dataFrame.DataFrame: raise NotImplementedError( - f"GeoSeries.area is not supported. Use bigframes.bigquery.st_area(series), instead. {constants.FEEDBACK_LINK}" - ) + f"GeoSeries.area is not supported. Use bigframes.bigquery.st_area(series), instead. {constants.FEEDBACK_LINK}" + ) diff --git a/bigframes/operations/__init__.py b/bigframes/operations/__init__.py index 0ad728acdb..1a54d99626 100644 --- a/bigframes/operations/__init__.py +++ b/bigframes/operations/__init__.py @@ -84,7 +84,7 @@ SqlScalarOp, where_op, ) -from bigframes.operations.geo_ops import geo_x_op, geo_y_op, geo_area_op +from bigframes.operations.geo_ops import geo_area_op, geo_x_op, geo_y_op from bigframes.operations.json_ops import ( JSONExtract, JSONExtractArray, diff --git a/tests/system/small/geopandas/test_geoseries.py b/tests/system/small/geopandas/test_geoseries.py index 0d2b6f0c2a..548c6f5d59 100644 --- a/tests/system/small/geopandas/test_geoseries.py +++ b/tests/system/small/geopandas/test_geoseries.py @@ -16,7 +16,7 @@ import google.api_core.exceptions import pandas as pd import pytest -from shapely.geometry import Polygon, LineString, Point +from shapely.geometry import LineString, Point, Polygon import bigframes.geopandas import bigframes.series @@ -65,17 +65,16 @@ def test_geo_y(urban_areas_dfs): def test_geo_area_not_supported(urban_areas_dfs): - series = bigframes.pandas.Series( - [ - Polygon([(0, 0), (1, 1), (0, 1)]), - Polygon([(10, 0), (10, 5), (0, 0)]), - Polygon([(0, 0), (2, 2), (2, 0)]), - LineString([(0, 0), (1, 1), (0, 1)]), - Point(0, 1) - ], dtype=geopandas.array.GeometryDtype() - ) - bf_series: bigframes.geopandas.GeoSeries = series.geo - with pytest.raises(NotImplementedError): - bf_series.area() - - + series = bigframes.pandas.Series( + [ + Polygon([(0, 0), (1, 1), (0, 1)]), + Polygon([(10, 0), (10, 5), (0, 0)]), + Polygon([(0, 0), (2, 2), (2, 0)]), + LineString([(0, 0), (1, 1), (0, 1)]), + Point(0, 1), + ], + dtype=geopandas.array.GeometryDtype(), + ) + bf_series: bigframes.geopandas.GeoSeries = series.geo + with pytest.raises(NotImplementedError): + bf_series.area() From 6331915043f71103075463491f90f1a9ea98881d Mon Sep 17 00:00:00 2001 From: Arwa Date: Thu, 23 Jan 2025 16:28:39 -0600 Subject: [PATCH 03/15] fix import error --- tests/system/small/geopandas/test_geoseries.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system/small/geopandas/test_geoseries.py b/tests/system/small/geopandas/test_geoseries.py index 548c6f5d59..295f3b2da4 100644 --- a/tests/system/small/geopandas/test_geoseries.py +++ b/tests/system/small/geopandas/test_geoseries.py @@ -16,7 +16,7 @@ import google.api_core.exceptions import pandas as pd import pytest -from shapely.geometry import LineString, Point, Polygon +from shapely.geometry import LineString, Point, Polygon # type: ignore import bigframes.geopandas import bigframes.series From 0cb819ed6af635d943e52969b88142b02baf79fb Mon Sep 17 00:00:00 2001 From: Arwa Date: Fri, 24 Jan 2025 10:55:54 -0600 Subject: [PATCH 04/15] fix format and return type --- bigframes/geopandas/geoseries.py | 2 +- tests/system/small/geopandas/test_geoseries.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bigframes/geopandas/geoseries.py b/bigframes/geopandas/geoseries.py index 848e0d7ef0..7b1d4bcdfa 100644 --- a/bigframes/geopandas/geoseries.py +++ b/bigframes/geopandas/geoseries.py @@ -42,7 +42,7 @@ def y(self) -> bigframes.series.Series: return series @property - def area(self, crs=None) -> bigframes.dataFrame.DataFrame: + def area(self, crs=None) -> bigframes.series.Series: raise NotImplementedError( f"GeoSeries.area is not supported. Use bigframes.bigquery.st_area(series), instead. {constants.FEEDBACK_LINK}" ) diff --git a/tests/system/small/geopandas/test_geoseries.py b/tests/system/small/geopandas/test_geoseries.py index 295f3b2da4..e274e6e13d 100644 --- a/tests/system/small/geopandas/test_geoseries.py +++ b/tests/system/small/geopandas/test_geoseries.py @@ -16,7 +16,7 @@ import google.api_core.exceptions import pandas as pd import pytest -from shapely.geometry import LineString, Point, Polygon # type: ignore +from shapely.geometry import LineString, Point, Polygon # type: ignore import bigframes.geopandas import bigframes.series From df075dd4784264d0a918880feb7da5659a6d72e9 Mon Sep 17 00:00:00 2001 From: Arwa Date: Fri, 24 Jan 2025 12:28:53 -0600 Subject: [PATCH 05/15] update test --- .../system/small/geopandas/test_geoseries.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/tests/system/small/geopandas/test_geoseries.py b/tests/system/small/geopandas/test_geoseries.py index e274e6e13d..fd699dc11b 100644 --- a/tests/system/small/geopandas/test_geoseries.py +++ b/tests/system/small/geopandas/test_geoseries.py @@ -12,7 +12,11 @@ # See the License for the specific language governing permissions and # limitations under the License. +import re + +import bigframes_vendored.constants as constants import geopandas # type: ignore +from geopandas.array import GeometryDtype import google.api_core.exceptions import pandas as pd import pytest @@ -64,8 +68,8 @@ def test_geo_y(urban_areas_dfs): ) -def test_geo_area_not_supported(urban_areas_dfs): - series = bigframes.pandas.Series( +def test_geo_area_not_supported(): + s = bigframes.pandas.Series( [ Polygon([(0, 0), (1, 1), (0, 1)]), Polygon([(10, 0), (10, 5), (0, 0)]), @@ -73,8 +77,13 @@ def test_geo_area_not_supported(urban_areas_dfs): LineString([(0, 0), (1, 1), (0, 1)]), Point(0, 1), ], - dtype=geopandas.array.GeometryDtype(), + dtype=GeometryDtype(), ) - bf_series: bigframes.geopandas.GeoSeries = series.geo - with pytest.raises(NotImplementedError): + bf_series: bigframes.geopandas.GeoSeries = s.geo + with pytest.raises( + NotImplementedError, + match=re.escape( + f"GeoSeries.area is not supported. Use bigframes.bigquery.st_area(series), instead. {constants.FEEDBACK_LINK}" + ), + ): bf_series.area() From d86e441cddfcf5b2e8bd2dde57dd245a252dbbf9 Mon Sep 17 00:00:00 2001 From: Arwa Date: Fri, 24 Jan 2025 16:55:43 -0600 Subject: [PATCH 06/15] add type ignore flag --- tests/system/small/geopandas/test_geoseries.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system/small/geopandas/test_geoseries.py b/tests/system/small/geopandas/test_geoseries.py index fd699dc11b..609bf0083d 100644 --- a/tests/system/small/geopandas/test_geoseries.py +++ b/tests/system/small/geopandas/test_geoseries.py @@ -16,7 +16,7 @@ import bigframes_vendored.constants as constants import geopandas # type: ignore -from geopandas.array import GeometryDtype +from geopandas.array import GeometryDtype # type:ignore import google.api_core.exceptions import pandas as pd import pytest From e613b64e4caa7e8d219dcdddebd1151c3c8f4b10 Mon Sep 17 00:00:00 2001 From: Arwa Date: Mon, 3 Feb 2025 16:21:10 -0600 Subject: [PATCH 07/15] add and test st_area --- bigframes/bigquery/__init__.py | 3 + bigframes/bigquery/_operations/geo.py | 93 +++++++++++++++++++ tests/system/small/bigquery/test_geo.py | 47 ++++++++++ .../system/small/geopandas/test_geoseries.py | 2 +- .../bigframes_vendored/geopandas/geoseries.py | 11 ++- 5 files changed, 152 insertions(+), 4 deletions(-) create mode 100644 bigframes/bigquery/_operations/geo.py create mode 100644 tests/system/small/bigquery/test_geo.py diff --git a/bigframes/bigquery/__init__.py b/bigframes/bigquery/__init__.py index 21e61bc4b1..56aee38bfe 100644 --- a/bigframes/bigquery/__init__.py +++ b/bigframes/bigquery/__init__.py @@ -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, @@ -45,6 +46,8 @@ "array_length", "array_agg", "array_to_string", + # geo ops + "st_area", # json ops "json_set", "json_extract", diff --git a/bigframes/bigquery/_operations/geo.py b/bigframes/bigquery/_operations/geo.py new file mode 100644 index 0000000000..262ced4fe8 --- /dev/null +++ b/bigframes/bigquery/_operations/geo.py @@ -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 diff --git a/tests/system/small/bigquery/test_geo.py b/tests/system/small/bigquery/test_geo.py new file mode 100644 index 0000000000..2b4a8bea79 --- /dev/null +++ b/tests/system/small/bigquery/test_geo.py @@ -0,0 +1,47 @@ +# 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. + +import geopandas # type: ignore +import pandas as pd +from shapely.geometry import LineString, Point, Polygon # type: ignore + +import bigframes.bigquery as bbq +import bigframes.geopandas +import bigframes.series + + +def test_geo_st_area(): + data = [ + 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), + ] + + geopd_s = geopandas.GeoSeries(data=data, crs="EPSG:4326") + geobf_s = bigframes.geopandas.GeoSeries(data=data) + + # Round both results to get an approximately similar output + geopd_s_result = geopd_s.to_crs(26393).area.round(-7) + geobf_s_result = bbq.st_area(geobf_s).to_pandas().round(-7) + + pd.testing.assert_series_equal( + geobf_s_result, + geopd_s_result, + check_dtype=False, + check_index_type=False, + check_exact=False, + rtol=1, + ) diff --git a/tests/system/small/geopandas/test_geoseries.py b/tests/system/small/geopandas/test_geoseries.py index 609bf0083d..2967e4d247 100644 --- a/tests/system/small/geopandas/test_geoseries.py +++ b/tests/system/small/geopandas/test_geoseries.py @@ -86,4 +86,4 @@ def test_geo_area_not_supported(): f"GeoSeries.area is not supported. Use bigframes.bigquery.st_area(series), instead. {constants.FEEDBACK_LINK}" ), ): - bf_series.area() + bf_series.area diff --git a/third_party/bigframes_vendored/geopandas/geoseries.py b/third_party/bigframes_vendored/geopandas/geoseries.py index 88a5044edf..44694b81d9 100644 --- a/third_party/bigframes_vendored/geopandas/geoseries.py +++ b/third_party/bigframes_vendored/geopandas/geoseries.py @@ -17,8 +17,9 @@ class GeoSeries: >>> import bigframes.geopandas >>> import bigframes.pandas as bpd - >>> bpd.options.display.progress_bar = None >>> from shapely.geometry import Point + >>> bpd.options.display.progress_bar = None + >>> s = bigframes.geopandas.GeoSeries([Point(1, 1), Point(2, 2), Point(3, 3)]) >>> s 0 POINT (1 1) @@ -43,9 +44,9 @@ def x(self) -> bigframes.series.Series: **Examples:** >>> import bigframes.pandas as bpd - >>> bpd.options.display.progress_bar = None >>> import geopandas.array >>> import shapely + >>> bpd.options.display.progress_bar = None >>> series = bpd.Series( ... [shapely.Point(1, 2), shapely.Point(2, 3), shapely.Point(3, 4)], @@ -70,9 +71,9 @@ def y(self) -> bigframes.series.Series: **Examples:** >>> import bigframes.pandas as bpd - >>> bpd.options.display.progress_bar = None >>> import geopandas.array >>> import shapely + >>> bpd.options.display.progress_bar = None >>> series = bpd.Series( ... [shapely.Point(1, 2), shapely.Point(2, 3), shapely.Point(3, 4)], @@ -104,5 +105,9 @@ def area(self, crs=None) -> bigframes.series.Series: Returns: float: Series of float representing the areas. + + Raises: + NotImplementedError: + GeoSeries.area is not supported. Use bigframes.bigquery.st_area(series) insetead. """ raise NotImplementedError(constants.ABSTRACT_METHOD_ERROR_MESSAGE) From 77b1ceabde6cf04f623bc40f4e6f7691e559ff5f Mon Sep 17 00:00:00 2001 From: Arwa Date: Mon, 3 Feb 2025 17:21:47 -0600 Subject: [PATCH 08/15] update goseries notebook with area and st_area --- notebooks/geo/geoseries.ipynb | 220 ++++++++++++++++++++++++++++------ 1 file changed, 184 insertions(+), 36 deletions(-) diff --git a/notebooks/geo/geoseries.ipynb b/notebooks/geo/geoseries.ipynb index 160d19ce91..b6107b1c0d 100644 --- a/notebooks/geo/geoseries.ipynb +++ b/notebooks/geo/geoseries.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": 27, "metadata": {}, "outputs": [], "source": [ @@ -30,7 +30,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 28, "metadata": {}, "outputs": [], "source": [ @@ -50,13 +50,15 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ + "/usr/local/google/home/arwas/src1/python-bigquery-dataframes/venv/lib/python3.9/site-packages/IPython/core/interactiveshell.py:3550: UserWarning: Reading cached table from 2025-02-03 22:54:14.603760+00:00 to avoid incompatibilies with previous reads of this table. To read the latest version, set `use_cache=False` or close the current session with Session.close() or bigframes.pandas.close_session().\n", + " exec(code_obj, self.user_global_ns, self.user_ns)\n", "/usr/local/google/home/arwas/src1/python-bigquery-dataframes/bigframes/session/_io/bigquery/read_gbq_table.py:274: DefaultIndexWarning: Table 'bigquery-public-data.geo_us_boundaries.counties' is clustered and/or partitioned, but BigQuery DataFrames was not able to find a suitable index. To avoid this warning, set at least one of: `index_col` or `filters`.\n", " warnings.warn(msg, category=bfe.DefaultIndexWarning)\n" ] @@ -75,7 +77,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 30, "metadata": {}, "outputs": [], "source": [ @@ -98,21 +100,21 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "54 POINT (-93.47523 45.00612)\n", - "256 POINT (-89.60507 42.67552)\n", - "266 POINT (-104.11408 39.31516)\n", - "485 POINT (-91.23193 32.34688)\n", - "765 POINT (-83.42808 38.20427)\n", + "7 POINT (-82.42267 38.14364)\n", + "34 POINT (-89.99324 34.87427)\n", + "87 POINT (-81.86504 29.98658)\n", + "234 POINT (-97.29122 32.77212)\n", + "280 POINT (-94.53725 43.67712)\n", "Name: int_point_geom, dtype: geometry" ] }, - "execution_count": 12, + "execution_count": 31, "metadata": {}, "output_type": "execute_result" } @@ -138,21 +140,21 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "0 POINT (-86.87338 38.37334)\n", - "1 POINT (-118.48037 46.25461)\n", - "2 POINT (-92.5617 32.30429)\n", - "3 POINT (-83.46189 39.55525)\n", - "4 POINT (-119.46779 47.21363)\n", + "0 POINT (-82.42267 38.14364)\n", + "1 POINT (-89.99324 34.87427)\n", + "2 POINT (-81.86504 29.98658)\n", + "3 POINT (-97.29122 32.77212)\n", + "4 POINT (-94.53725 43.67712)\n", "dtype: geometry" ] }, - "execution_count": 6, + "execution_count": 32, "metadata": {}, "output_type": "execute_result" } @@ -180,21 +182,21 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "0 -86.873385\n", - "1 -118.48037\n", - "2 -92.5617\n", - "3 -83.461893\n", - "4 -119.467788\n", + "0 -82.422666\n", + "1 -89.99324\n", + "2 -81.865036\n", + "3 -97.291224\n", + "4 -94.537252\n", "dtype: Float64" ] }, - "execution_count": 7, + "execution_count": 33, "metadata": {}, "output_type": "execute_result" } @@ -212,21 +214,21 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "0 38.373344\n", - "1 46.254606\n", - "2 32.30429\n", - "3 39.555246\n", - "4 47.213633\n", + "0 38.143642\n", + "1 34.874266\n", + "2 29.986584\n", + "3 32.772119\n", + "4 43.677118\n", "dtype: Float64" ] }, - "execution_count": 8, + "execution_count": 34, "metadata": {}, "output_type": "execute_result" } @@ -251,7 +253,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 35, "metadata": {}, "outputs": [ { @@ -285,7 +287,7 @@ "dtype: Float64" ] }, - "execution_count": 13, + "execution_count": 35, "metadata": {}, "output_type": "execute_result" } @@ -303,7 +305,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 36, "metadata": {}, "outputs": [ { @@ -337,7 +339,7 @@ "dtype: Float64" ] }, - "execution_count": 14, + "execution_count": 36, "metadata": {}, "output_type": "execute_result" } @@ -345,6 +347,152 @@ "source": [ "point_geom_series.geo.y" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Retrive the `area` of different geometrty shapes. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1. Create a gemometry collection from local data with `Peek`" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "18 POLYGON ((-84.14483 42.59956, -84.14475 42.598...\n", + "86 POLYGON ((-90.3355 43.20969, -90.33658 43.2097...\n", + "177 POLYGON ((-117.49995 48.65277, -117.49995 48.6...\n", + "208 POLYGON ((-84.69253 36.43547, -84.69244 36.435...\n", + "300 POLYGON ((-92.08001 43.42885, -92.08 43.4277, ...\n", + "Name: county_geom, dtype: geometry" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "geom_series = df[\"county_geom\"].peek(n = 5)\n", + "geom_series" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Convert the geometry collection to `bigframes.gopandas.GeoSeries`" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0 POLYGON ((-84.14483 42.59956, -84.14475 42.598...\n", + "1 POLYGON ((-90.3355 43.20969, -90.33658 43.2097...\n", + "2 POLYGON ((-117.49995 48.65277, -117.49995 48.6...\n", + "3 POLYGON ((-84.69253 36.43547, -84.69244 36.435...\n", + "4 POLYGON ((-92.08001 43.42885, -92.08 43.4277, ...\n", + "dtype: geometry" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "five_geom = bigframes.geopandas.GeoSeries(\n", + " [point for point in geom_series]\n", + ")\n", + "five_geom" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Note: `bigframes.geopandas.GeoSeries.area` raises NotImplementedError. " + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "ename": "NotImplementedError", + "evalue": "GeoSeries.area is not supported. Use bigframes.bigquery.st_area(series), instead. Share your usecase with the BigQuery DataFrames team at the https://bit.ly/bigframes-feedback survey.You are currently running BigFrames version 1.34.0", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNotImplementedError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[39], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mfive_geom\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43marea\u001b[49m\n", + "File \u001b[0;32m~/src1/python-bigquery-dataframes/bigframes/geopandas/geoseries.py:46\u001b[0m, in \u001b[0;36mGeoSeries.area\u001b[0;34m(self, crs)\u001b[0m\n\u001b[1;32m 44\u001b[0m \u001b[38;5;129m@property\u001b[39m\n\u001b[1;32m 45\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21marea\u001b[39m(\u001b[38;5;28mself\u001b[39m, crs\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m bigframes\u001b[38;5;241m.\u001b[39mseries\u001b[38;5;241m.\u001b[39mSeries:\n\u001b[0;32m---> 46\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mNotImplementedError\u001b[39;00m(\n\u001b[1;32m 47\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mGeoSeries.area is not supported. Use bigframes.bigquery.st_area(series), instead. \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mconstants\u001b[38;5;241m.\u001b[39mFEEDBACK_LINK\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 48\u001b[0m )\n", + "\u001b[0;31mNotImplementedError\u001b[0m: GeoSeries.area is not supported. Use bigframes.bigquery.st_area(series), instead. Share your usecase with the BigQuery DataFrames team at the https://bit.ly/bigframes-feedback survey.You are currently running BigFrames version 1.34.0" + ] + } + ], + "source": [ + "five_geom.area" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Use `bigframes.bigquery.st_area` to retirive the `area` in square meters instead. See: https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_area" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [], + "source": [ + "import bigframes.bigquery as bbq" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0 1513674358.195978\n", + "1 1985759505.347184\n", + "2 3680789945.308985\n", + "3 1380731457.626208\n", + "4 1784154727.752777\n", + "dtype: Float64" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "geom_area = bbq.st_area(five_geom)\n", + "geom_area" + ] } ], "metadata": { From 37533f8e4495e9397bf2ca12ae0d922c3854c5af Mon Sep 17 00:00:00 2001 From: Arwa Date: Tue, 4 Feb 2025 10:27:29 -0600 Subject: [PATCH 09/15] ignore mypy error --- bigframes/geopandas/geoseries.py | 22 ++++++++++++++++++- .../bigframes_vendored/geopandas/geoseries.py | 21 ------------------ 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/bigframes/geopandas/geoseries.py b/bigframes/geopandas/geoseries.py index 7b1d4bcdfa..bc0482f60d 100644 --- a/bigframes/geopandas/geoseries.py +++ b/bigframes/geopandas/geoseries.py @@ -41,8 +41,28 @@ def y(self) -> bigframes.series.Series: 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: + 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}" ) diff --git a/third_party/bigframes_vendored/geopandas/geoseries.py b/third_party/bigframes_vendored/geopandas/geoseries.py index 44694b81d9..d84dec94a8 100644 --- a/third_party/bigframes_vendored/geopandas/geoseries.py +++ b/third_party/bigframes_vendored/geopandas/geoseries.py @@ -90,24 +90,3 @@ def y(self) -> bigframes.series.Series: Return the y location (latitude) of point geometries. """ raise NotImplementedError(constants.ABSTRACT_METHOD_ERROR_MESSAGE) - - @property - def area(self, crs=None) -> bigframes.series.Series: - """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: - float: - Series of float representing the areas. - - Raises: - NotImplementedError: - GeoSeries.area is not supported. Use bigframes.bigquery.st_area(series) insetead. - """ - raise NotImplementedError(constants.ABSTRACT_METHOD_ERROR_MESSAGE) From bbbcced07f6ce8f76c3f9e026683c890a6d15694 Mon Sep 17 00:00:00 2001 From: Arwa Date: Tue, 4 Feb 2025 10:39:36 -0600 Subject: [PATCH 10/15] update the notebook --- notebooks/geo/geoseries.ipynb | 232 +++++++--------------------------- 1 file changed, 48 insertions(+), 184 deletions(-) diff --git a/notebooks/geo/geoseries.ipynb b/notebooks/geo/geoseries.ipynb index b6107b1c0d..720788181e 100644 --- a/notebooks/geo/geoseries.ipynb +++ b/notebooks/geo/geoseries.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 27, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -30,14 +30,13 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "import bigframes\n", "import bigframes.geopandas\n", "import bigframes.pandas as bpd\n", - "import shapely\n", "bpd.options.display.progress_bar = None" ] }, @@ -50,16 +49,14 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "/usr/local/google/home/arwas/src1/python-bigquery-dataframes/venv/lib/python3.9/site-packages/IPython/core/interactiveshell.py:3550: UserWarning: Reading cached table from 2025-02-03 22:54:14.603760+00:00 to avoid incompatibilies with previous reads of this table. To read the latest version, set `use_cache=False` or close the current session with Session.close() or bigframes.pandas.close_session().\n", - " exec(code_obj, self.user_global_ns, self.user_ns)\n", - "/usr/local/google/home/arwas/src1/python-bigquery-dataframes/bigframes/session/_io/bigquery/read_gbq_table.py:274: DefaultIndexWarning: Table 'bigquery-public-data.geo_us_boundaries.counties' is clustered and/or partitioned, but BigQuery DataFrames was not able to find a suitable index. To avoid this warning, set at least one of: `index_col` or `filters`.\n", + "/usr/local/google/home/arwas/src1/python-bigquery-dataframes/bigframes/session/_io/bigquery/read_gbq_table.py:280: DefaultIndexWarning: Table 'bigquery-public-data.geo_us_boundaries.counties' is clustered and/or partitioned, but BigQuery DataFrames was not able to find a suitable index. To avoid this warning, set at least one of: `index_col` or `filters`.\n", " warnings.warn(msg, category=bfe.DefaultIndexWarning)\n" ] } @@ -77,7 +74,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -100,21 +97,21 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "7 POINT (-82.42267 38.14364)\n", - "34 POINT (-89.99324 34.87427)\n", - "87 POINT (-81.86504 29.98658)\n", - "234 POINT (-97.29122 32.77212)\n", - "280 POINT (-94.53725 43.67712)\n", + "78 POINT (-95.84727 44.4092)\n", + "130 POINT (-94.90431 41.67918)\n", + "544 POINT (-95.85272 40.38739)\n", + "995 POINT (-101.83333 47.30715)\n", + "1036 POINT (-88.36343 37.20952)\n", "Name: int_point_geom, dtype: geometry" ] }, - "execution_count": 31, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -140,21 +137,21 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "0 POINT (-82.42267 38.14364)\n", - "1 POINT (-89.99324 34.87427)\n", - "2 POINT (-81.86504 29.98658)\n", - "3 POINT (-97.29122 32.77212)\n", - "4 POINT (-94.53725 43.67712)\n", + "0 POINT (-95.84727 44.4092)\n", + "1 POINT (-94.90431 41.67918)\n", + "2 POINT (-95.85272 40.38739)\n", + "3 POINT (-101.83333 47.30715)\n", + "4 POINT (-88.36343 37.20952)\n", "dtype: geometry" ] }, - "execution_count": 32, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } @@ -182,21 +179,21 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "0 -82.422666\n", - "1 -89.99324\n", - "2 -81.865036\n", - "3 -97.291224\n", - "4 -94.537252\n", + "0 -95.847268\n", + "1 -94.904312\n", + "2 -95.852721\n", + "3 -101.833328\n", + "4 -88.363426\n", "dtype: Float64" ] }, - "execution_count": 33, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -214,21 +211,21 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "0 38.143642\n", - "1 34.874266\n", - "2 29.986584\n", - "3 32.772119\n", - "4 43.677118\n", + "0 44.409195\n", + "1 41.679178\n", + "2 40.387389\n", + "3 47.307147\n", + "4 37.209517\n", "dtype: Float64" ] }, - "execution_count": 34, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -253,45 +250,9 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 10, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 -101.298265\n", - "1 -99.111085\n", - "2 -66.58687\n", - "3 -102.601791\n", - "4 -71.578625\n", - "5 -88.961529\n", - "6 -87.492986\n", - "7 -82.422666\n", - "8 -100.208166\n", - "9 -85.815939\n", - "10 -101.681133\n", - "11 -119.516659\n", - "12 -89.398306\n", - "13 -107.78848\n", - "14 -91.159306\n", - "15 -113.887042\n", - "16 -83.470416\n", - "17 -98.520146\n", - "18 -83.911718\n", - "19 -87.321865\n", - "20 -91.727626\n", - "21 -93.466093\n", - "22 -101.143324\n", - "23 -78.657634\n", - "24 -94.272323\n", - "dtype: Float64" - ] - }, - "execution_count": 35, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "point_geom_series.geo.x" ] @@ -305,45 +266,9 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 46.710819\n", - "1 29.353661\n", - "2 18.211152\n", - "3 38.835646\n", - "4 41.869768\n", - "5 39.860237\n", - "6 36.892059\n", - "7 38.143642\n", - "8 34.524623\n", - "9 30.862007\n", - "10 40.180165\n", - "11 46.228125\n", - "12 36.054196\n", - "13 38.154731\n", - "14 38.761902\n", - "15 44.928506\n", - "16 30.447232\n", - "17 29.448671\n", - "18 42.602532\n", - "19 34.529776\n", - "20 33.957675\n", - "21 42.037538\n", - "22 29.875285\n", - "23 36.299884\n", - "24 44.821657\n", - "dtype: Float64" - ] - }, - "execution_count": 36, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "point_geom_series.geo.y" ] @@ -352,37 +277,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Retrive the `area` of different geometrty shapes. " + "## Retrive the `area` of different geometry shapes. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### 1. Create a gemometry collection from local data with `Peek`" + "### 1. Create a geometry collection from local data with `Peek`" ] }, { "cell_type": "code", - "execution_count": 37, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "18 POLYGON ((-84.14483 42.59956, -84.14475 42.598...\n", - "86 POLYGON ((-90.3355 43.20969, -90.33658 43.2097...\n", - "177 POLYGON ((-117.49995 48.65277, -117.49995 48.6...\n", - "208 POLYGON ((-84.69253 36.43547, -84.69244 36.435...\n", - "300 POLYGON ((-92.08001 43.42885, -92.08 43.4277, ...\n", - "Name: county_geom, dtype: geometry" - ] - }, - "execution_count": 37, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "geom_series = df[\"county_geom\"].peek(n = 5)\n", "geom_series" @@ -397,25 +306,9 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 POLYGON ((-84.14483 42.59956, -84.14475 42.598...\n", - "1 POLYGON ((-90.3355 43.20969, -90.33658 43.2097...\n", - "2 POLYGON ((-117.49995 48.65277, -117.49995 48.6...\n", - "3 POLYGON ((-84.69253 36.43547, -84.69244 36.435...\n", - "4 POLYGON ((-92.08001 43.42885, -92.08 43.4277, ...\n", - "dtype: geometry" - ] - }, - "execution_count": 38, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "five_geom = bigframes.geopandas.GeoSeries(\n", " [point for point in geom_series]\n", @@ -432,24 +325,11 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "ename": "NotImplementedError", - "evalue": "GeoSeries.area is not supported. Use bigframes.bigquery.st_area(series), instead. Share your usecase with the BigQuery DataFrames team at the https://bit.ly/bigframes-feedback survey.You are currently running BigFrames version 1.34.0", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNotImplementedError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[39], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mfive_geom\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43marea\u001b[49m\n", - "File \u001b[0;32m~/src1/python-bigquery-dataframes/bigframes/geopandas/geoseries.py:46\u001b[0m, in \u001b[0;36mGeoSeries.area\u001b[0;34m(self, crs)\u001b[0m\n\u001b[1;32m 44\u001b[0m \u001b[38;5;129m@property\u001b[39m\n\u001b[1;32m 45\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21marea\u001b[39m(\u001b[38;5;28mself\u001b[39m, crs\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m bigframes\u001b[38;5;241m.\u001b[39mseries\u001b[38;5;241m.\u001b[39mSeries:\n\u001b[0;32m---> 46\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mNotImplementedError\u001b[39;00m(\n\u001b[1;32m 47\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mGeoSeries.area is not supported. Use bigframes.bigquery.st_area(series), instead. \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mconstants\u001b[38;5;241m.\u001b[39mFEEDBACK_LINK\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 48\u001b[0m )\n", - "\u001b[0;31mNotImplementedError\u001b[0m: GeoSeries.area is not supported. Use bigframes.bigquery.st_area(series), instead. Share your usecase with the BigQuery DataFrames team at the https://bit.ly/bigframes-feedback survey.You are currently running BigFrames version 1.34.0" - ] - } - ], + "outputs": [], "source": [ - "five_geom.area" + "five_geom.x" ] }, { @@ -470,25 +350,9 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 1513674358.195978\n", - "1 1985759505.347184\n", - "2 3680789945.308985\n", - "3 1380731457.626208\n", - "4 1784154727.752777\n", - "dtype: Float64" - ] - }, - "execution_count": 41, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "geom_area = bbq.st_area(five_geom)\n", "geom_area" From 5508ddad7472a5a33e987c6528f27e5b0b58e2f0 Mon Sep 17 00:00:00 2001 From: Arwa Date: Tue, 4 Feb 2025 11:33:52 -0600 Subject: [PATCH 11/15] update the notebook --- notebooks/geo/geoseries.ipynb | 239 ++++++++++++++++++++++++++-------- 1 file changed, 186 insertions(+), 53 deletions(-) diff --git a/notebooks/geo/geoseries.ipynb b/notebooks/geo/geoseries.ipynb index 720788181e..00836fb303 100644 --- a/notebooks/geo/geoseries.ipynb +++ b/notebooks/geo/geoseries.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -30,7 +30,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -49,7 +49,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 3, "metadata": {}, "outputs": [ { @@ -74,7 +74,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -97,21 +97,21 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "78 POINT (-95.84727 44.4092)\n", - "130 POINT (-94.90431 41.67918)\n", - "544 POINT (-95.85272 40.38739)\n", - "995 POINT (-101.83333 47.30715)\n", - "1036 POINT (-88.36343 37.20952)\n", + "140 POINT (-83.05291 39.07134)\n", + "175 POINT (-87.01289 30.70127)\n", + "297 POINT (-91.79642 45.89249)\n", + "336 POINT (-99.00458 44.54671)\n", + "419 POINT (-78.20759 38.90822)\n", "Name: int_point_geom, dtype: geometry" ] }, - "execution_count": 6, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -128,30 +128,23 @@ "### Convert the five geo points to `bigframes.gopandas.GeoSeries`" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Note: TypeError is raised if the GEOGRAPHY column contains geometry type other than `Point`." - ] - }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "0 POINT (-95.84727 44.4092)\n", - "1 POINT (-94.90431 41.67918)\n", - "2 POINT (-95.85272 40.38739)\n", - "3 POINT (-101.83333 47.30715)\n", - "4 POINT (-88.36343 37.20952)\n", + "0 POINT (-83.05291 39.07134)\n", + "1 POINT (-87.01289 30.70127)\n", + "2 POINT (-91.79642 45.89249)\n", + "3 POINT (-99.00458 44.54671)\n", + "4 POINT (-78.20759 38.90822)\n", "dtype: geometry" ] }, - "execution_count": 7, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -170,6 +163,13 @@ "### Retrieve the x (longitude) and y (latitude) from the GeoSeries with `.x` and `.y`." ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Note: TypeError is raised if `.x` and `.y` are used with a geometry type other than `Point`." + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -179,21 +179,21 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "0 -95.847268\n", - "1 -94.904312\n", - "2 -95.852721\n", - "3 -101.833328\n", - "4 -88.363426\n", + "0 -83.052911\n", + "1 -87.01289\n", + "2 -91.796422\n", + "3 -99.004575\n", + "4 -78.207594\n", "dtype: Float64" ] }, - "execution_count": 8, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } @@ -211,21 +211,21 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "0 44.409195\n", - "1 41.679178\n", - "2 40.387389\n", - "3 47.307147\n", - "4 37.209517\n", + "0 39.071341\n", + "1 30.701269\n", + "2 45.892488\n", + "3 44.546713\n", + "4 38.908221\n", "dtype: Float64" ] }, - "execution_count": 9, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -250,9 +250,45 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 9, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "0 -101.298265\n", + "1 -99.111085\n", + "2 -66.58687\n", + "3 -102.601791\n", + "4 -71.578625\n", + "5 -88.961529\n", + "6 -87.492986\n", + "7 -82.422666\n", + "8 -100.208166\n", + "9 -85.815939\n", + "10 -101.681133\n", + "11 -119.516659\n", + "12 -89.398306\n", + "13 -107.78848\n", + "14 -91.159306\n", + "15 -113.887042\n", + "16 -83.470416\n", + "17 -98.520146\n", + "18 -83.911718\n", + "19 -87.321865\n", + "20 -91.727626\n", + "21 -93.466093\n", + "22 -101.143324\n", + "23 -78.657634\n", + "24 -94.272323\n", + "dtype: Float64" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "point_geom_series.geo.x" ] @@ -266,9 +302,45 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "0 46.710819\n", + "1 29.353661\n", + "2 18.211152\n", + "3 38.835646\n", + "4 41.869768\n", + "5 39.860237\n", + "6 36.892059\n", + "7 38.143642\n", + "8 34.524623\n", + "9 30.862007\n", + "10 40.180165\n", + "11 46.228125\n", + "12 36.054196\n", + "13 38.154731\n", + "14 38.761902\n", + "15 44.928506\n", + "16 30.447232\n", + "17 29.448671\n", + "18 42.602532\n", + "19 34.529776\n", + "20 33.957675\n", + "21 42.037538\n", + "22 29.875285\n", + "23 36.299884\n", + "24 44.821657\n", + "dtype: Float64" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "point_geom_series.geo.y" ] @@ -289,9 +361,25 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "137 POLYGON ((-87.07312 38.43705, -87.07312 38.436...\n", + "164 POLYGON ((-118.79351 46.29057, -118.79516 46.2...\n", + "333 POLYGON ((-92.77367 32.29536, -92.77357 32.288...\n", + "703 POLYGON ((-83.66352 39.61772, -83.66373 39.615...\n", + "846 POLYGON ((-119.5578 47.44114, -119.55812 47.44...\n", + "Name: county_geom, dtype: geometry" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "geom_series = df[\"county_geom\"].peek(n = 5)\n", "geom_series" @@ -306,9 +394,25 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "0 POLYGON ((-87.07312 38.43705, -87.07312 38.436...\n", + "1 POLYGON ((-118.79351 46.29057, -118.79516 46.2...\n", + "2 POLYGON ((-92.77367 32.29536, -92.77357 32.288...\n", + "3 POLYGON ((-83.66352 39.61772, -83.66373 39.615...\n", + "4 POLYGON ((-119.5578 47.44114, -119.55812 47.44...\n", + "dtype: geometry" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "five_geom = bigframes.geopandas.GeoSeries(\n", " [point for point in geom_series]\n", @@ -325,11 +429,24 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "NotImplementedError", + "evalue": "GeoSeries.area is not supported. Use bigframes.bigquery.st_area(series), instead. Share your usecase with the BigQuery DataFrames team at the https://bit.ly/bigframes-feedback survey.You are currently running BigFrames version 1.34.0", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNotImplementedError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[13], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mfive_geom\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43marea\u001b[49m\n", + "File \u001b[0;32m~/src1/python-bigquery-dataframes/bigframes/geopandas/geoseries.py:66\u001b[0m, in \u001b[0;36mGeoSeries.area\u001b[0;34m(self, crs)\u001b[0m\n\u001b[1;32m 47\u001b[0m \u001b[38;5;129m@property\u001b[39m\n\u001b[1;32m 48\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21marea\u001b[39m(\u001b[38;5;28mself\u001b[39m, crs\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m bigframes\u001b[38;5;241m.\u001b[39mseries\u001b[38;5;241m.\u001b[39mSeries: \u001b[38;5;66;03m# type: ignore\u001b[39;00m\n\u001b[1;32m 49\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Returns a Series containing the area of each geometry in the GeoSeries\u001b[39;00m\n\u001b[1;32m 50\u001b[0m \u001b[38;5;124;03m expressed in the units of the CRS.\u001b[39;00m\n\u001b[1;32m 51\u001b[0m \n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 64\u001b[0m \u001b[38;5;124;03m GeoSeries.area is not supported. Use bigframes.bigquery.st_area(series), insetead.\u001b[39;00m\n\u001b[1;32m 65\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m---> 66\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mNotImplementedError\u001b[39;00m(\n\u001b[1;32m 67\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mGeoSeries.area is not supported. Use bigframes.bigquery.st_area(series), instead. \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mconstants\u001b[38;5;241m.\u001b[39mFEEDBACK_LINK\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 68\u001b[0m )\n", + "\u001b[0;31mNotImplementedError\u001b[0m: GeoSeries.area is not supported. Use bigframes.bigquery.st_area(series), instead. Share your usecase with the BigQuery DataFrames team at the https://bit.ly/bigframes-feedback survey.You are currently running BigFrames version 1.34.0" + ] + } + ], "source": [ - "five_geom.x" + "five_geom.area" ] }, { @@ -341,7 +458,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 14, "metadata": {}, "outputs": [], "source": [ @@ -350,9 +467,25 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "0 1126739085.191096\n", + "1 3355859279.2291\n", + "2 1503893853.137287\n", + "3 1053155291.382645\n", + "4 7210025834.985987\n", + "dtype: Float64" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "geom_area = bbq.st_area(five_geom)\n", "geom_area" From 11d06039791c9a2a0fe7718a586911980c1ae0f3 Mon Sep 17 00:00:00 2001 From: Arwa Date: Tue, 4 Feb 2025 12:38:08 -0600 Subject: [PATCH 12/15] ignore exception in notebook --- notebooks/geo/geoseries.ipynb | 82 +++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 37 deletions(-) diff --git a/notebooks/geo/geoseries.ipynb b/notebooks/geo/geoseries.ipynb index 00836fb303..7dc4c596ca 100644 --- a/notebooks/geo/geoseries.ipynb +++ b/notebooks/geo/geoseries.ipynb @@ -103,11 +103,11 @@ { "data": { "text/plain": [ - "140 POINT (-83.05291 39.07134)\n", - "175 POINT (-87.01289 30.70127)\n", - "297 POINT (-91.79642 45.89249)\n", - "336 POINT (-99.00458 44.54671)\n", - "419 POINT (-78.20759 38.90822)\n", + "37 POINT (-91.19496 39.98605)\n", + "406 POINT (-84.86717 33.92103)\n", + "926 POINT (-82.47974 35.33641)\n", + "940 POINT (-75.50298 39.09709)\n", + "996 POINT (-92.56434 39.8298)\n", "Name: int_point_geom, dtype: geometry" ] }, @@ -136,11 +136,11 @@ { "data": { "text/plain": [ - "0 POINT (-83.05291 39.07134)\n", - "1 POINT (-87.01289 30.70127)\n", - "2 POINT (-91.79642 45.89249)\n", - "3 POINT (-99.00458 44.54671)\n", - "4 POINT (-78.20759 38.90822)\n", + "0 POINT (-91.19496 39.98605)\n", + "1 POINT (-84.86717 33.92103)\n", + "2 POINT (-82.47974 35.33641)\n", + "3 POINT (-75.50298 39.09709)\n", + "4 POINT (-92.56434 39.8298)\n", "dtype: geometry" ] }, @@ -185,11 +185,11 @@ { "data": { "text/plain": [ - "0 -83.052911\n", - "1 -87.01289\n", - "2 -91.796422\n", - "3 -99.004575\n", - "4 -78.207594\n", + "0 -91.194961\n", + "1 -84.867169\n", + "2 -82.479741\n", + "3 -75.502982\n", + "4 -92.56434\n", "dtype: Float64" ] }, @@ -217,11 +217,11 @@ { "data": { "text/plain": [ - "0 39.071341\n", - "1 30.701269\n", - "2 45.892488\n", - "3 44.546713\n", - "4 38.908221\n", + "0 39.986053\n", + "1 33.92103\n", + "2 35.336415\n", + "3 39.097088\n", + "4 39.829795\n", "dtype: Float64" ] }, @@ -367,11 +367,11 @@ { "data": { "text/plain": [ - "137 POLYGON ((-87.07312 38.43705, -87.07312 38.436...\n", - "164 POLYGON ((-118.79351 46.29057, -118.79516 46.2...\n", - "333 POLYGON ((-92.77367 32.29536, -92.77357 32.288...\n", - "703 POLYGON ((-83.66352 39.61772, -83.66373 39.615...\n", - "846 POLYGON ((-119.5578 47.44114, -119.55812 47.44...\n", + "10 POLYGON ((-101.7778 40.34969, -101.77812 40.34...\n", + "127 POLYGON ((-89.22333 44.50398, -89.22334 44.499...\n", + "253 POLYGON ((-76.69446 37.07288, -76.69515 37.072...\n", + "261 POLYGON ((-98.70136 44.45055, -98.70136 44.450...\n", + "303 POLYGON ((-85.99565 30.28131, -85.99566 30.280...\n", "Name: county_geom, dtype: geometry" ] }, @@ -400,11 +400,11 @@ { "data": { "text/plain": [ - "0 POLYGON ((-87.07312 38.43705, -87.07312 38.436...\n", - "1 POLYGON ((-118.79351 46.29057, -118.79516 46.2...\n", - "2 POLYGON ((-92.77367 32.29536, -92.77357 32.288...\n", - "3 POLYGON ((-83.66352 39.61772, -83.66373 39.615...\n", - "4 POLYGON ((-119.5578 47.44114, -119.55812 47.44...\n", + "0 POLYGON ((-101.7778 40.34969, -101.77812 40.34...\n", + "1 POLYGON ((-89.22333 44.50398, -89.22334 44.499...\n", + "2 POLYGON ((-76.69446 37.07288, -76.69515 37.072...\n", + "3 POLYGON ((-98.70136 44.45055, -98.70136 44.450...\n", + "4 POLYGON ((-85.99565 30.28131, -85.99566 30.280...\n", "dtype: geometry" ] }, @@ -422,7 +422,11 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "tags": [ + "raises-exception" + ] + }, "source": [ "## Note: `bigframes.geopandas.GeoSeries.area` raises NotImplementedError. " ] @@ -430,7 +434,11 @@ { "cell_type": "code", "execution_count": 13, - "metadata": {}, + "metadata": { + "tags": [ + "raises-exception" + ] + }, "outputs": [ { "ename": "NotImplementedError", @@ -473,11 +481,11 @@ { "data": { "text/plain": [ - "0 1126739085.191096\n", - "1 3355859279.2291\n", - "2 1503893853.137287\n", - "3 1053155291.382645\n", - "4 7210025834.985987\n", + "0 2382382043.48891\n", + "1 1977633097.26862\n", + "2 939388839.499466\n", + "3 3269015229.381782\n", + "4 2678752241.321673\n", "dtype: Float64" ] }, From d121a1a94908c5f139548d7a379a5b14e2363224 Mon Sep 17 00:00:00 2001 From: Arwa Date: Tue, 4 Feb 2025 13:55:02 -0600 Subject: [PATCH 13/15] update test data and add comment --- tests/system/small/bigquery/test_geo.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/tests/system/small/bigquery/test_geo.py b/tests/system/small/bigquery/test_geo.py index 2b4a8bea79..687c298b28 100644 --- a/tests/system/small/bigquery/test_geo.py +++ b/tests/system/small/bigquery/test_geo.py @@ -23,9 +23,9 @@ def test_geo_st_area(): data = [ - 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)]), + Polygon([(0.000, 0.0), (0.001, 0.001), (0.000, 0.001)]), + Polygon([(0.0010, 0.004), (0.009, 0.005), (0.0010, 0.005)]), + Polygon([(0.001, 0.001), (0.002, 0.001), (0.002, 0.002)]), LineString([(0, 0), (1, 1), (0, 1)]), Point(0, 1), ] @@ -33,9 +33,14 @@ def test_geo_st_area(): geopd_s = geopandas.GeoSeries(data=data, crs="EPSG:4326") geobf_s = bigframes.geopandas.GeoSeries(data=data) - # Round both results to get an approximately similar output - geopd_s_result = geopd_s.to_crs(26393).area.round(-7) - geobf_s_result = bbq.st_area(geobf_s).to_pandas().round(-7) + # For `geopd_s`, the data was further projected with `geopandas.GeoSeries.to_crs` + # to `to_crs(26393)` to get the area in square meter. See: https://geopandas.org/en/stable/docs/user_guide/projections.html + # and https://spatialreference.org/ref/epsg/26393/. We then rounded both results + # to get them as close to each other as possible. Initially, the area results + # were +ten-millions. We added more zeros after the decimal point to round the + # area results to the nearest thousands. + geopd_s_result = geopd_s.to_crs(26393).area.round(-3) + geobf_s_result = bbq.st_area(geobf_s).to_pandas().round(-3) pd.testing.assert_series_equal( geobf_s_result, From 8530103f668daf9e9de606c34276bba9259418a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Swe=C3=B1a=20=28Swast=29?= Date: Tue, 4 Feb 2025 14:23:46 -0600 Subject: [PATCH 14/15] Update tests/system/small/bigquery/test_geo.py --- tests/system/small/bigquery/test_geo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system/small/bigquery/test_geo.py b/tests/system/small/bigquery/test_geo.py index 687c298b28..5b028dbfc1 100644 --- a/tests/system/small/bigquery/test_geo.py +++ b/tests/system/small/bigquery/test_geo.py @@ -40,7 +40,7 @@ def test_geo_st_area(): # were +ten-millions. We added more zeros after the decimal point to round the # area results to the nearest thousands. geopd_s_result = geopd_s.to_crs(26393).area.round(-3) - geobf_s_result = bbq.st_area(geobf_s).to_pandas().round(-3) + assert geobf_s_result.iloc[0] >= 1000 pd.testing.assert_series_equal( geobf_s_result, From f288e4fcda625481310636d2f73b79deb8a530c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Swe=C3=B1a=20=28Swast=29?= Date: Tue, 4 Feb 2025 14:27:12 -0600 Subject: [PATCH 15/15] Update tests/system/small/bigquery/test_geo.py --- tests/system/small/bigquery/test_geo.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/system/small/bigquery/test_geo.py b/tests/system/small/bigquery/test_geo.py index 5b028dbfc1..7d38cd7d91 100644 --- a/tests/system/small/bigquery/test_geo.py +++ b/tests/system/small/bigquery/test_geo.py @@ -40,6 +40,7 @@ def test_geo_st_area(): # were +ten-millions. We added more zeros after the decimal point to round the # area results to the nearest thousands. geopd_s_result = geopd_s.to_crs(26393).area.round(-3) + geobf_s_result = bbq.st_area(geobf_s).to_pandas().round(-3) assert geobf_s_result.iloc[0] >= 1000 pd.testing.assert_series_equal(