{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Copyright 2025 Google LLC\n",
    "#\n",
    "# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
    "# you may not use this file except in compliance with the License.\n",
    "# You may obtain a copy of the License at\n",
    "#\n",
    "#     https://www.apache.org/licenses/LICENSE-2.0\n",
    "#\n",
    "# Unless required by applicable law or agreed to in writing, software\n",
    "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
    "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
    "# See the License for the specific language governing permissions and\n",
    "# limitations under the License."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Analyzing a GEOGRAPHY column with `bigframes.geopandas.GeoSeries`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import bigframes\n",
    "import bigframes.geopandas\n",
    "import bigframes.pandas as bpd\n",
    "bpd.options.display.progress_bar = None"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1. Load the Counties table from the Census Bureau US Boundaries dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/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\n",
      "and/or partitioned, but BigQuery DataFrames was not able to find a\n",
      "suitable index. To avoid this warning, set at least one of:\n",
      "`index_col` or `filters`.\n",
      "  warnings.warn(msg, category=bfe.DefaultIndexWarning)\n"
     ]
    }
   ],
   "source": [
    "df = bpd.read_gbq(\"bigquery-public-data.geo_us_boundaries.counties\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2. Create a series from the int_point_geom column"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "point_geom_series = df['int_point_geom']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## The `GeoSeries` constructor accepts local data or a `bigframes.pandas.Series` object."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1. Create a GeoSeries from local data with `Peek`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "18      POINT (-83.91172 42.60253)\n",
       "86      POINT (-90.13369 43.00102)\n",
       "177    POINT (-117.23219 48.54382)\n",
       "208     POINT (-84.50352 36.43523)\n",
       "300     POINT (-91.85079 43.29299)\n",
       "Name: int_point_geom, dtype: geometry"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "five_geo_points = point_geom_series.peek(n = 5)\n",
    "five_geo_points"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2. Convert the five geo points to `GeoSeries`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0     POINT (-83.91172 42.60253)\n",
       "1     POINT (-90.13369 43.00102)\n",
       "2    POINT (-117.23219 48.54382)\n",
       "3     POINT (-84.50352 36.43523)\n",
       "4     POINT (-91.85079 43.29299)\n",
       "dtype: geometry"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "geo_points = bigframes.geopandas.GeoSeries(\n",
    "        [point for point in five_geo_points]\n",
    ")\n",
    "geo_points"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3. 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": {},
   "source": [
    "### `.x`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    -83.911718\n",
       "1    -90.133691\n",
       "2   -117.232191\n",
       "3     -84.50352\n",
       "4    -91.850788\n",
       "dtype: Float64"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "geo_points.x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### `.y`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    42.602532\n",
       "1    43.001021\n",
       "2    48.543825\n",
       "3    36.435234\n",
       "4    43.292989\n",
       "dtype: Float64"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "geo_points.y"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4. Alternatively, use the `.geo` accessor to access GeoSeries methods from a `bigframes.pandas.Series` object."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### `geo.x`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "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": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "point_geom_series.geo.x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### `geo.y`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "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": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "point_geom_series.geo.y"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Retrive the `area` of different geometry shapes. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1. Create a geometry collection from local data with `Peek`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "304    POLYGON ((-88.69875 38.56219, -88.69876 38.562...\n",
       "288    POLYGON ((-100.55792 46.24588, -100.5579 46.24...\n",
       "42     POLYGON ((-98.09779 30.49744, -98.0978 30.4971...\n",
       "775    POLYGON ((-90.33573 41.67043, -90.33592 41.669...\n",
       "83     POLYGON ((-85.98402 35.6552, -85.98402 35.6551...\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"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2. Convert the geometry collection to `GeoSeries`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    POLYGON ((-88.69875 38.56219, -88.69876 38.562...\n",
       "1    POLYGON ((-100.55792 46.24588, -100.5579 46.24...\n",
       "2    POLYGON ((-98.09779 30.49744, -98.0978 30.4971...\n",
       "3    POLYGON ((-90.33573 41.67043, -90.33592 41.669...\n",
       "4    POLYGON ((-85.98402 35.6552, -85.98402 35.6551...\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",
    ")\n",
    "five_geom"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": [
     "raises-exception"
    ]
   },
   "source": [
    "## Note: `GeoSeries.area` raises NotImplementedError.  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "tags": [
     "raises-exception"
    ]
   },
   "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.41.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:67\u001b[0m, in \u001b[0;36mGeoSeries.area\u001b[0;34m(self, crs)\u001b[0m\n\u001b[1;32m     48\u001b[0m \u001b[38;5;129m@property\u001b[39m\n\u001b[1;32m     49\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     50\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     51\u001b[0m \u001b[38;5;124;03m    expressed in the units of the CRS.\u001b[39;00m\n\u001b[1;32m     52\u001b[0m \n\u001b[0;32m   (...)\u001b[0m\n\u001b[1;32m     65\u001b[0m \u001b[38;5;124;03m            GeoSeries.area is not supported. Use bigframes.bigquery.st_area(series), instead.\u001b[39;00m\n\u001b[1;32m     66\u001b[0m \u001b[38;5;124;03m    \"\"\"\u001b[39;00m\n\u001b[0;32m---> 67\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mNotImplementedError\u001b[39;00m(\n\u001b[1;32m     68\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     69\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.41.0."
     ]
    }
   ],
   "source": [
    "five_geom.area"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 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"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "import bigframes.bigquery as bbq"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    1851741847.416806\n",
       "1    4018075889.856168\n",
       "2    2652483302.084653\n",
       "3     1167209931.07698\n",
       "4      1124055521.2818\n",
       "dtype: Float64"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "geom_area = bbq.st_area(five_geom)\n",
    "geom_area"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Use `GeoSeries.from_xy()` to create a GeoSeries of `Point` geometries. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1. Reuse the `geo_points.x` and `geo_points.y` results by passing them to `.from_xy()` "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0     POINT (-83.91172 42.60253)\n",
       "1     POINT (-90.13369 43.00102)\n",
       "2    POINT (-117.23219 48.54382)\n",
       "3     POINT (-84.50352 36.43523)\n",
       "4     POINT (-91.85079 43.29299)\n",
       "dtype: geometry"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bigframes.geopandas.GeoSeries.from_xy(geo_points.x, geo_points.y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Use `GeoSeries.to_wkt()` to convert geo points from geometry data type to Well-Knonw Text (WKT)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1. Reuse the `geo_points`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0     POINT(-83.9117183 42.6025316)\n",
       "1     POINT(-90.1336915 43.0010208)\n",
       "2    POINT(-117.2321913 48.5438247)\n",
       "3        POINT(-84.50352 36.435234)\n",
       "4      POINT(-91.850788 43.2929889)\n",
       "dtype: string"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "geo_to_wkts = bigframes.geopandas.GeoSeries.to_wkt(geo_points)\n",
    "geo_to_wkts"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Use `GeoSeries.from_wkt()` to convert geo points from Well-Knonw Text (WKT) to geometry data type."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1. Reuse `geo_to_wkts` results from `GeoSeries.to_wkts`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0     POINT (-83.91172 42.60253)\n",
       "1     POINT (-90.13369 43.00102)\n",
       "2    POINT (-117.23219 48.54382)\n",
       "3     POINT (-84.50352 36.43523)\n",
       "4     POINT (-91.85079 43.29299)\n",
       "dtype: geometry"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "wkts_from_geo = bigframes.geopandas.GeoSeries.from_wkt(geo_to_wkts)\n",
    "wkts_from_geo"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Discover the set-theoretic boundary of geometry objects with `GeoSeries.boundary`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0       POLYGON ((0 0, 1 1, 0 1, 0 0))\n",
       "1    POLYGON ((10 0, 10 5, 0 0, 10 0))\n",
       "2       POLYGON ((0 0, 2 2, 2 0, 0 0))\n",
       "3           LINESTRING (0 0, 1 1, 0 1)\n",
       "4                          POINT (0 1)\n",
       "dtype: geometry"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from shapely.geometry import Polygon, LineString, Point\n",
    "geom_obj = bigframes.geopandas.GeoSeries(\n",
    "            [\n",
    "                Polygon([(0, 0), (1, 1), (0, 1)]),\n",
    "                Polygon([(10, 0), (10, 5), (0, 0)]),\n",
    "                Polygon([(0, 0), (2, 2), (2, 0)]),\n",
    "                LineString([(0, 0), (1, 1), (0, 1)]),\n",
    "                Point(0, 1),\n",
    "            ]\n",
    ")\n",
    "geom_obj"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0       LINESTRING (0 0, 1 1, 0 1, 0 0)\n",
       "1    LINESTRING (10 0, 10 5, 0 0, 10 0)\n",
       "2       LINESTRING (0 0, 2 2, 2 0, 0 0)\n",
       "3                 MULTIPOINT (0 0, 0 1)\n",
       "4              GEOMETRYCOLLECTION EMPTY\n",
       "dtype: geometry"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "geom_obj.geo.boundary"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Find the `difference` between two `GeoSeries` "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Reuse `five_geom` and `geom_obj` to find the difference between the geometry objects"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "tags": [
     "raises-exception"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    POLYGON ((-88.69875 38.56219, -88.69876 38.562...\n",
       "1    POLYGON ((-100.55792 46.24588, -100.5579 46.24...\n",
       "2                             GEOMETRYCOLLECTION EMPTY\n",
       "3    POLYGON ((-90.33573 41.67043, -90.33592 41.669...\n",
       "4    POLYGON ((-85.98402 35.6552, -85.98402 35.6551...\n",
       "dtype: geometry"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "five_geom.difference(geom_obj)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Find the difference between a `GeoSeries` and a single geometry shape."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    POLYGON ((-88.69875 38.56219, -88.69876 38.562...\n",
       "1                                                 None\n",
       "2                                                 None\n",
       "3                                                 None\n",
       "4                                                 None\n",
       "dtype: geometry"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "five_geom.difference([Polygon([(0, 0), (10, 0), (10, 10), (0, 0)])])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Find the difference in `GeoSeries` with the same shapes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    GEOMETRYCOLLECTION EMPTY\n",
       "1    GEOMETRYCOLLECTION EMPTY\n",
       "2    GEOMETRYCOLLECTION EMPTY\n",
       "3    GEOMETRYCOLLECTION EMPTY\n",
       "4    GEOMETRYCOLLECTION EMPTY\n",
       "dtype: geometry"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "five_geom.difference(five_geom)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## You can also use`BigQuery.st_difference()` to find the difference between two `GeoSeries`. See, https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_difference"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    POLYGON ((-88.69875 38.56219, -88.69876 38.562...\n",
       "1    POLYGON ((-100.55792 46.24588, -100.5579 46.24...\n",
       "2                             GEOMETRYCOLLECTION EMPTY\n",
       "3    POLYGON ((-90.33573 41.67043, -90.33592 41.669...\n",
       "4    POLYGON ((-85.98402 35.6552, -85.98402 35.6551...\n",
       "dtype: geometry"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bbq.st_difference(five_geom, geom_obj)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Find the difference between a `GeoSeries` and a single geometry shape."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    POLYGON ((-88.69875 38.56219, -88.69876 38.562...\n",
       "1                                                 None\n",
       "2                                                 None\n",
       "3                                                 None\n",
       "4                                                 None\n",
       "dtype: geometry"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bbq.st_difference(five_geom, [Polygon([(0, 0), (10, 0), (10, 10), (0, 0)])])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Find the difference in GeoSeries with the same shapes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    GEOMETRYCOLLECTION EMPTY\n",
       "1    GEOMETRYCOLLECTION EMPTY\n",
       "2    GEOMETRYCOLLECTION EMPTY\n",
       "3    GEOMETRYCOLLECTION EMPTY\n",
       "4    GEOMETRYCOLLECTION EMPTY\n",
       "dtype: geometry"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bbq.st_difference(geom_obj, geom_obj)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Use `GeoSeries.intersection()` to find the intersecting points in two geometry shapes "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Reuse `wkts_from_geo` and `geom_obj`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0                             GEOMETRYCOLLECTION EMPTY\n",
       "1                             GEOMETRYCOLLECTION EMPTY\n",
       "2    POLYGON ((-98.09779 30.49744, -98.0978 30.4971...\n",
       "3                             GEOMETRYCOLLECTION EMPTY\n",
       "4                             GEOMETRYCOLLECTION EMPTY\n",
       "dtype: geometry"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "five_geom.intersection(geom_obj)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Find the difference between a `GeoSeries` and a single geometry shape."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    GEOMETRYCOLLECTION EMPTY\n",
       "1                        None\n",
       "2                        None\n",
       "3                        None\n",
       "4                        None\n",
       "dtype: geometry"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "five_geom.intersection([Polygon([(0, 0), (10, 0), (10, 10), (0, 0)])])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## You can also use`BigQuery.st_intersection()` to find the intersecting points between two `GeoSeries`. See, https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_intersection"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0                             GEOMETRYCOLLECTION EMPTY\n",
       "1                             GEOMETRYCOLLECTION EMPTY\n",
       "2    POLYGON ((-98.09779 30.49744, -98.0978 30.4971...\n",
       "3                             GEOMETRYCOLLECTION EMPTY\n",
       "4                             GEOMETRYCOLLECTION EMPTY\n",
       "dtype: geometry"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bbq.st_intersection(five_geom, geom_obj)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Find the difference between a `GeoSeries` and a single geometry shape."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    GEOMETRYCOLLECTION EMPTY\n",
       "1                        None\n",
       "2                        None\n",
       "3                        None\n",
       "4                        None\n",
       "dtype: geometry"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bbq.st_intersection(five_geom, [Polygon([(0, 0), (1, 0), (10, 10), (0, 0)])])"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.19"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
