Skip to content

Instantly share code, notes, and snippets.

@michaelwooley
Last active September 12, 2023 00:57
Show Gist options
  • Save michaelwooley/b1eaea53b3d764427125e3033a264fdd to your computer and use it in GitHub Desktop.
Save michaelwooley/b1eaea53b3d764427125e3033a264fdd to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"id": "ad44aff2-4a6f-4b6c-87ed-d4cc1db9738d",
"metadata": {},
"source": [
"# Shapely intersection investigation\n",
"\n",
"See [Stackoverflow answer](https://stackoverflow.com/a/75821572/3422060)."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "84d17bbe-0ac8-4d81-81ac-bad9b84b3d57",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"100.0\" height=\"100.0\" viewBox=\"-0.12 -0.12 3.24 3.24\" preserveAspectRatio=\"xMinYMin meet\"><g transform=\"matrix(1,0,0,-1,0,3.0)\"><g><path fill-rule=\"evenodd\" fill=\"#ff3333\" stroke=\"#555555\" stroke-width=\"0.06480000000000001\" opacity=\"0.6\" d=\"M 0.0,0.0 L 0.0,1.0 L 1.0,1.0 L 1.0,0.0 L 0.0,0.0 z\" /><path fill-rule=\"evenodd\" fill=\"#ff3333\" stroke=\"#555555\" stroke-width=\"0.06480000000000001\" opacity=\"0.6\" d=\"M 2.0,2.0 L 2.0,3.0 L 3.0,3.0 L 3.0,2.0 L 2.0,2.0 z\" /><path fill-rule=\"evenodd\" fill=\"#ff3333\" stroke=\"#555555\" stroke-width=\"0.06480000000000001\" opacity=\"0.6\" d=\"M 0.5,0.5 L 0.5,1.5 L 1.5,1.5 L 1.5,0.5 L 0.5,0.5 z\" /></g></g></svg>"
],
"text/plain": [
"<shapely.geometry.multipolygon.MultiPolygon at 0x7f24482ad820>"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import shapely.geometry as sg\n",
"import shapely.affinity\n",
"\n",
"a = sg.Polygon([(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)])\n",
"b = shapely.affinity.translate(a, xoff=2, yoff=2)\n",
"c = shapely.affinity.translate(a, xoff=0.5, yoff=0.5)\n",
"\n",
"sg.MultiPolygon([a, b, c])"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "ddd405b5-79fa-45d3-81b5-f1d78c7dfadf",
"metadata": {},
"outputs": [],
"source": [
"def check_intersects_first(p0: sg.Polygon, p1: sg.Polygon) -> float:\n",
" if not p0.intersects(p1):\n",
" return 0\n",
" return p0.intersection(p1).area / p0.union(p1).area\n",
"\n",
"\n",
"def do_no_check(p0: sg.Polygon, p1: sg.Polygon) -> float:\n",
" return p0.intersection(p1).area / p0.union(p1).area"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "1cbf8732-abae-4d3d-a777-11e400791120",
"metadata": {},
"outputs": [],
"source": [
"assert check_intersects_first(a,b) == do_no_check(a,b) == 0\n",
"assert check_intersects_first(a,c) == do_no_check(a,c)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "e7ecc377-fc6c-4afe-87af-76815e9bebbb",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"================================================================================\n",
"Without checking intersects first.\n",
"--------------------------------------------------------------------------------\n",
"No intersection\n",
"1.52 µs ± 39.2 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)\n",
"Has Intersection\n",
"46.1 µs ± 96 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n",
"--------------------------------------------------------------------------------\n",
"\n"
]
}
],
"source": [
"print(\"=\"*80)\n",
"print(\"Without checking intersects first.\")\n",
"print(\"-\"*80)\n",
"print(\"No intersection\")\n",
"%timeit check_intersects_first(a,b)\n",
"\n",
"print(\"Has Intersection\")\n",
"%timeit check_intersects_first(a,c)\n",
"print(\"-\"*80)\n",
"print()"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "a3749687-d094-4af2-819d-e8e75129d175",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"================================================================================\n",
"Without checking intersects first.\n",
"--------------------------------------------------------------------------------\n",
"No intersection\n",
"23.3 µs ± 1.01 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n",
"Has Intersection\n",
"43.7 µs ± 226 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n",
"--------------------------------------------------------------------------------\n"
]
}
],
"source": [
"print(\"=\"*80)\n",
"print(\"Without checking intersects first.\")\n",
"print(\"-\"*80)\n",
"print(\"No intersection\")\n",
"%timeit do_no_check(a,b)\n",
"\n",
"print(\"Has Intersection\")\n",
"%timeit do_no_check(a,c)\n",
"print(\"-\"*80)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c56f4e28-7ca3-4b55-9df9-a79fd197f2a9",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "eaa6498a-8ea8-4b1e-ab35-75eed9f9d28a",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"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.7"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
@seangrogan
Copy link

Is your 4th input correct? Should it be "With checking intersects first."?

@michaelwooley
Copy link
Author

Yep, the 4th cell print statement should be "With checking intersects first." Thanks @seangrogan!

@seangrogan
Copy link

Yep, the 4th cell print statement should be "With checking intersects first." Thanks @seangrogan!

No worries, thanks friend -- the intersect function you demonstrated helped me solve a problem today!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment