# 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
#
# https://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.
Analyzing a GEOGRAPHY column with bigframes.geopandas.GeoSeries#
import bigframes
import bigframes.geopandas
import bigframes.pandas as bpd
bpd.options.display.progress_bar = None
1. Load the Counties table from the Census Bureau US Boundaries dataset#
df = bpd.read_gbq("bigquery-public-data.geo_us_boundaries.counties")
/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`.
warnings.warn(msg, category=bfe.DefaultIndexWarning)
2. Create a series from the int_point_geom column#
point_geom_series = df['int_point_geom']
The GeoSeries constructor accepts local data or a bigframes.pandas.Series object.#
1. Create a GeoSeries from local data with Peek#
five_geo_points = point_geom_series.peek(n = 5)
five_geo_points
18 POINT (-83.91172 42.60253)
86 POINT (-90.13369 43.00102)
177 POINT (-117.23219 48.54382)
208 POINT (-84.50352 36.43523)
300 POINT (-91.85079 43.29299)
Name: int_point_geom, dtype: geometry
2. Convert the five geo points to GeoSeries#
geo_points = bigframes.geopandas.GeoSeries(
[point for point in five_geo_points]
)
geo_points
0 POINT (-83.91172 42.60253)
1 POINT (-90.13369 43.00102)
2 POINT (-117.23219 48.54382)
3 POINT (-84.50352 36.43523)
4 POINT (-91.85079 43.29299)
dtype: geometry
3. Retrieve the x (longitude) and y (latitude) from the GeoSeries with .x and .y.#
Note: TypeError is raised if .x and .y are used with a geometry type other than Point.#
.x#
geo_points.x
0 -83.911718
1 -90.133691
2 -117.232191
3 -84.50352
4 -91.850788
dtype: Float64
.y#
geo_points.y
0 42.602532
1 43.001021
2 48.543825
3 36.435234
4 43.292989
dtype: Float64
4. Alternatively, use the .geo accessor to access GeoSeries methods from a bigframes.pandas.Series object.#
geo.x#
point_geom_series.geo.x
0 -101.298265
1 -99.111085
2 -66.58687
3 -102.601791
4 -71.578625
5 -88.961529
6 -87.492986
7 -82.422666
8 -100.208166
9 -85.815939
10 -101.681133
11 -119.516659
12 -89.398306
13 -107.78848
14 -91.159306
15 -113.887042
16 -83.470416
17 -98.520146
18 -83.911718
19 -87.321865
20 -91.727626
21 -93.466093
22 -101.143324
23 -78.657634
24 -94.272323
dtype: Float64
geo.y#
point_geom_series.geo.y
0 46.710819
1 29.353661
2 18.211152
3 38.835646
4 41.869768
5 39.860237
6 36.892059
7 38.143642
8 34.524623
9 30.862007
10 40.180165
11 46.228125
12 36.054196
13 38.154731
14 38.761902
15 44.928506
16 30.447232
17 29.448671
18 42.602532
19 34.529776
20 33.957675
21 42.037538
22 29.875285
23 36.299884
24 44.821657
dtype: Float64
Retrive the area of different geometry shapes.#
1. Create a geometry collection from local data with Peek#
geom_series = df["county_geom"].peek(n = 5)
geom_series
304 POLYGON ((-88.69875 38.56219, -88.69876 38.562...
288 POLYGON ((-100.55792 46.24588, -100.5579 46.24...
42 POLYGON ((-98.09779 30.49744, -98.0978 30.4971...
775 POLYGON ((-90.33573 41.67043, -90.33592 41.669...
83 POLYGON ((-85.98402 35.6552, -85.98402 35.6551...
Name: county_geom, dtype: geometry
2. Convert the geometry collection to GeoSeries#
five_geom = bigframes.geopandas.GeoSeries(
[point for point in geom_series]
)
five_geom
0 POLYGON ((-88.69875 38.56219, -88.69876 38.562...
1 POLYGON ((-100.55792 46.24588, -100.5579 46.24...
2 POLYGON ((-98.09779 30.49744, -98.0978 30.4971...
3 POLYGON ((-90.33573 41.67043, -90.33592 41.669...
4 POLYGON ((-85.98402 35.6552, -85.98402 35.6551...
dtype: geometry
Note: GeoSeries.area raises NotImplementedError.#
five_geom.area
---------------------------------------------------------------------------
NotImplementedError Traceback (most recent call last)
Cell In[13], line 1
----> 1 five_geom.area
File ~/src1/python-bigquery-dataframes/bigframes/geopandas/geoseries.py:67, in GeoSeries.area(self, crs)
48 @property
49 def area(self, crs=None) -> bigframes.series.Series: # type: ignore
50 """Returns a Series containing the area of each geometry in the GeoSeries
51 expressed in the units of the CRS.
52
(...)
65 GeoSeries.area is not supported. Use bigframes.bigquery.st_area(series), instead.
66 """
---> 67 raise NotImplementedError(
68 f"GeoSeries.area is not supported. Use bigframes.bigquery.st_area(series), instead. {constants.FEEDBACK_LINK}"
69 )
NotImplementedError: 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.41.0.
3. Use bigframes.bigquery.st_area to retrieve the area in square meters instead. See: https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_area#
import bigframes.bigquery as bbq
geom_area = bbq.st_area(five_geom)
geom_area
0 1851741847.416806
1 4018075889.856168
2 2652483302.084653
3 1167209931.07698
4 1124055521.2818
dtype: Float64
Use GeoSeries.from_xy() to create a GeoSeries of Point geometries.#
1. Reuse the geo_points.x and geo_points.y results by passing them to .from_xy()#
bigframes.geopandas.GeoSeries.from_xy(geo_points.x, geo_points.y)
0 POINT (-83.91172 42.60253)
1 POINT (-90.13369 43.00102)
2 POINT (-117.23219 48.54382)
3 POINT (-84.50352 36.43523)
4 POINT (-91.85079 43.29299)
dtype: geometry
Use GeoSeries.to_wkt() to convert geo points from geometry data type to Well-Knonw Text (WKT).#
1. Reuse the geo_points#
geo_to_wkts = bigframes.geopandas.GeoSeries.to_wkt(geo_points)
geo_to_wkts
0 POINT(-83.9117183 42.6025316)
1 POINT(-90.1336915 43.0010208)
2 POINT(-117.2321913 48.5438247)
3 POINT(-84.50352 36.435234)
4 POINT(-91.850788 43.2929889)
dtype: string
Use GeoSeries.from_wkt() to convert geo points from Well-Knonw Text (WKT) to geometry data type.#
1. Reuse geo_to_wkts results from GeoSeries.to_wkts#
wkts_from_geo = bigframes.geopandas.GeoSeries.from_wkt(geo_to_wkts)
wkts_from_geo
0 POINT (-83.91172 42.60253)
1 POINT (-90.13369 43.00102)
2 POINT (-117.23219 48.54382)
3 POINT (-84.50352 36.43523)
4 POINT (-91.85079 43.29299)
dtype: geometry
Discover the set-theoretic boundary of geometry objects with GeoSeries.boundary#
from shapely.geometry import Polygon, LineString, Point
geom_obj = bigframes.geopandas.GeoSeries(
[
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),
]
)
geom_obj
0 POLYGON ((0 0, 1 1, 0 1, 0 0))
1 POLYGON ((10 0, 10 5, 0 0, 10 0))
2 POLYGON ((0 0, 2 2, 2 0, 0 0))
3 LINESTRING (0 0, 1 1, 0 1)
4 POINT (0 1)
dtype: geometry
geom_obj.geo.boundary
0 LINESTRING (0 0, 1 1, 0 1, 0 0)
1 LINESTRING (10 0, 10 5, 0 0, 10 0)
2 LINESTRING (0 0, 2 2, 2 0, 0 0)
3 MULTIPOINT (0 0, 0 1)
4 GEOMETRYCOLLECTION EMPTY
dtype: geometry
Find the difference between two GeoSeries#
Reuse five_geom and geom_obj to find the difference between the geometry objects#
five_geom.difference(geom_obj)
0 POLYGON ((-88.69875 38.56219, -88.69876 38.562...
1 POLYGON ((-100.55792 46.24588, -100.5579 46.24...
2 GEOMETRYCOLLECTION EMPTY
3 POLYGON ((-90.33573 41.67043, -90.33592 41.669...
4 POLYGON ((-85.98402 35.6552, -85.98402 35.6551...
dtype: geometry
Find the difference between a GeoSeries and a single geometry shape.#
five_geom.difference([Polygon([(0, 0), (10, 0), (10, 10), (0, 0)])])
0 POLYGON ((-88.69875 38.56219, -88.69876 38.562...
1 None
2 None
3 None
4 None
dtype: geometry
Find the difference in GeoSeries with the same shapes#
five_geom.difference(five_geom)
0 GEOMETRYCOLLECTION EMPTY
1 GEOMETRYCOLLECTION EMPTY
2 GEOMETRYCOLLECTION EMPTY
3 GEOMETRYCOLLECTION EMPTY
4 GEOMETRYCOLLECTION EMPTY
dtype: geometry
You can also useBigQuery.st_difference() to find the difference between two GeoSeries. See, https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_difference#
bbq.st_difference(five_geom, geom_obj)
0 POLYGON ((-88.69875 38.56219, -88.69876 38.562...
1 POLYGON ((-100.55792 46.24588, -100.5579 46.24...
2 GEOMETRYCOLLECTION EMPTY
3 POLYGON ((-90.33573 41.67043, -90.33592 41.669...
4 POLYGON ((-85.98402 35.6552, -85.98402 35.6551...
dtype: geometry
Find the difference between a GeoSeries and a single geometry shape.#
bbq.st_difference(five_geom, [Polygon([(0, 0), (10, 0), (10, 10), (0, 0)])])
0 POLYGON ((-88.69875 38.56219, -88.69876 38.562...
1 None
2 None
3 None
4 None
dtype: geometry
Find the difference in GeoSeries with the same shapes#
bbq.st_difference(geom_obj, geom_obj)
0 GEOMETRYCOLLECTION EMPTY
1 GEOMETRYCOLLECTION EMPTY
2 GEOMETRYCOLLECTION EMPTY
3 GEOMETRYCOLLECTION EMPTY
4 GEOMETRYCOLLECTION EMPTY
dtype: geometry
Use GeoSeries.intersection() to find the intersecting points in two geometry shapes#
Reuse wkts_from_geo and geom_obj#
five_geom.intersection(geom_obj)
0 GEOMETRYCOLLECTION EMPTY
1 GEOMETRYCOLLECTION EMPTY
2 POLYGON ((-98.09779 30.49744, -98.0978 30.4971...
3 GEOMETRYCOLLECTION EMPTY
4 GEOMETRYCOLLECTION EMPTY
dtype: geometry
Find the difference between a GeoSeries and a single geometry shape.#
five_geom.intersection([Polygon([(0, 0), (10, 0), (10, 10), (0, 0)])])
0 GEOMETRYCOLLECTION EMPTY
1 None
2 None
3 None
4 None
dtype: geometry
You can also useBigQuery.st_intersection() to find the intersecting points between two GeoSeries. See, https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_intersection#
bbq.st_intersection(five_geom, geom_obj)
0 GEOMETRYCOLLECTION EMPTY
1 GEOMETRYCOLLECTION EMPTY
2 POLYGON ((-98.09779 30.49744, -98.0978 30.4971...
3 GEOMETRYCOLLECTION EMPTY
4 GEOMETRYCOLLECTION EMPTY
dtype: geometry
Find the difference between a GeoSeries and a single geometry shape.#
bbq.st_intersection(five_geom, [Polygon([(0, 0), (1, 0), (10, 10), (0, 0)])])
0 GEOMETRYCOLLECTION EMPTY
1 None
2 None
3 None
4 None
dtype: geometry