Created
May 31, 2025 19:59
-
-
Save jGaboardi/0ad10b5a5bff253107f45719e86673a2 to your computer and use it in GitHub Desktop.
gh_214_topology_component_behavior
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {"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.13.3"}},"nbformat_minor":5,"nbformat":4,"cells":[{"id":"566b7674-dacd-48ad-ae13-d388428a6f16","cell_type":"markdown","source":"# Failure when calling `remove_interstitial_nodes()`\n\n* appears to...\n * happen when calling [remove_interstitial_nodes()](https://github.com/uscuni/neatnet/blob/84a1dcac84b50d88be1eed294d3e00546a6c5f73/neatnet/nodes.py#L345) vs. calling `fix_topology()` (where `remove_interstitial_nodes()` [is called internally](https://github.com/uscuni/neatnet/blob/84a1dcac84b50d88be1eed294d3e00546a6c5f73/neatnet/nodes.py#L491))\n * be based on 2 lines connecting 2 loops\n * [nodes.get_components()](https://github.com/uscuni/neatnet/blob/84a1dcac84b50d88be1eed294d3e00546a6c5f73/neatnet/nodes.py#L134-L192) returns this as considered 3 loops\n * no trouble with: {0, 1, 3+} connecting edges \n * need more logic [here](https://github.com/uscuni/neatnet/blob/84a1dcac84b50d88be1eed294d3e00546a6c5f73/neatnet/nodes.py#L174) in `nodes.get_components()`??\n * occur inconsistently depending on feature character (e.g., empirical vs. synthetic)","metadata":{}},{"id":"6d9229c4-10ee-4e59-b914-15ef2be6b4fd","cell_type":"code","source":"%load_ext watermark\n%watermark","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:31.171752Z","iopub.status.busy":"2025-05-31T19:55:31.171219Z","iopub.status.idle":"2025-05-31T19:55:31.200191Z","shell.execute_reply":"2025-05-31T19:55:31.199637Z","shell.execute_reply.started":"2025-05-31T19:55:31.171707Z"},"trusted":true},"outputs":[{"name":"stdout","output_type":"stream","text":"Last updated: 2025-05-31T15:55:31.191644-04:00\n\nPython implementation: CPython\nPython version : 3.13.3\nIPython version : 9.2.0\n\nCompiler : Clang 18.1.8 \nOS : Darwin\nRelease : 24.5.0\nMachine : arm64\nProcessor : arm\nCPU cores : 8\nArchitecture: 64bit\n\n"}],"execution_count":1},{"id":"c14a7ae4-01bf-4099-9728-51d3dd06d952","cell_type":"code","source":"import geopandas\nimport networkx\nimport numpy\nimport osmnx\nimport pandas\nimport shapely\n\nfrom shapely import Point, LineString\n\nimport neatnet","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:31.795093Z","iopub.status.busy":"2025-05-31T19:55:31.794358Z","iopub.status.idle":"2025-05-31T19:55:33.842958Z","shell.execute_reply":"2025-05-31T19:55:33.842702Z","shell.execute_reply.started":"2025-05-31T19:55:31.794997Z"},"trusted":true},"outputs":[],"execution_count":2},{"id":"71fc4a6a-2e49-4a2f-86ea-f1eb3df6e8c7","cell_type":"code","source":"%watermark -w\n%watermark -iv","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:34.468705Z","iopub.status.busy":"2025-05-31T19:55:34.467568Z","iopub.status.idle":"2025-05-31T19:55:34.485137Z","shell.execute_reply":"2025-05-31T19:55:34.484650Z","shell.execute_reply.started":"2025-05-31T19:55:34.468652Z"},"trusted":true},"outputs":[{"name":"stdout","output_type":"stream","text":"Watermark: 2.5.0\n\nosmnx : 2.0.3\ngeopandas: 1.0.1\nnumpy : 2.2.6\npandas : 2.2.3\nneatnet : 0.1.2.dev11+g84a1dca\nshapely : 2.1.1\nnetworkx : 3.4.2\n\n"}],"execution_count":3},{"id":"7085c4d9-d583-4152-82f7-ad611e7cc178","cell_type":"markdown","source":"## Empirical\n\n### Convert `.osm.xml` to undirected graph\n\n(includes all OSM objects)","metadata":{}},{"id":"5ec27955-609b-4c7b-9c3c-51fbd72d6080","cell_type":"code","source":"#osm_graph = osmnx.graph_from_xml(\"kennington.osm.xml\")\n#osm_graph = osmnx.projection.project_graph(osm_graph, to_crs=27700)\n#streets = osmnx.graph_to_gdfs(\n# osmnx.convert.to_undirected(osm_graph),\n# nodes=False,\n# edges=True,\n# node_geometry=False,\n# fill_edge_geometry=True,\n#).reset_index(drop=True)\n#streets.to_file(\"streets.geojson\", driver=\"GeoJSON\")\n#simplified = neatnet.neatify(streets)","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:35.523641Z","iopub.status.busy":"2025-05-31T19:55:35.522882Z","iopub.status.idle":"2025-05-31T19:55:35.529196Z","shell.execute_reply":"2025-05-31T19:55:35.528256Z","shell.execute_reply.started":"2025-05-31T19:55:35.523587Z"},"trusted":true},"outputs":[],"execution_count":4},{"id":"76d85542-04fd-4fe4-96d4-947df757e052","cell_type":"markdown","source":"### Prep subset for debugging\n\n* Run `neatnet` until [error location](https://github.com/uscuni/neatnet/blob/84a1dcac84b50d88be1eed294d3e00546a6c5f73/neatnet/simplify.py#L927)\n * errors out in [`remove_interstitial_nodes`](https://github.com/uscuni/neatnet/blob/84a1dcac84b50d88be1eed294d3e00546a6c5f73/neatnet/nodes.py#L345)\n * from [this call](https://github.com/uscuni/neatnet/blob/84a1dcac84b50d88be1eed294d3e00546a6c5f73/neatnet/simplify.py#L823) to `neatify_loop` \n* Save out input there by:\n\n```python\n(\n roads.drop(roads.index[r_idx])\n .reset_index(drop=True)\n .reset_index()\n .to_file(\"edges_fully_within_artifacts.geojson\", driver=\"GeoJSON\")\n)\nroads = remove_interstitial_nodes(roads.drop(roads.index[r_idx]))\n```","metadata":{}},{"id":"b298382d-cff4-46aa-8a4b-a4d9b54a5bba","cell_type":"code","source":"empirical_edges = geopandas.read_file(\"edges_fully_within_artifacts.geojson\")\nempirical_edges","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:36.718716Z","iopub.status.busy":"2025-05-31T19:55:36.717987Z","iopub.status.idle":"2025-05-31T19:55:36.899732Z","shell.execute_reply":"2025-05-31T19:55:36.899456Z","shell.execute_reply.started":"2025-05-31T19:55:36.718660Z"},"trusted":true},"outputs":[{"name":"stderr","output_type":"stream","text":"Skipping field highway: unsupported OGR type: 5\nSkipping field lanes: unsupported OGR type: 5\nSkipping field maxspeed: unsupported OGR type: 5\nSkipping field name: unsupported OGR type: 5\nSkipping field access: unsupported OGR type: 5\n"},{"data":{"text/html":"<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>index</th>\n <th>_status</th>\n <th>osmid</th>\n <th>oneway</th>\n <th>reversed</th>\n <th>length</th>\n <th>from</th>\n <th>to</th>\n <th>service</th>\n <th>width</th>\n <th>ref</th>\n <th>landuse</th>\n <th>bridge</th>\n <th>tunnel</th>\n <th>est_width</th>\n <th>area</th>\n <th>geometry</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>0</td>\n <td>changed</td>\n <td>1182255831</td>\n <td>False</td>\n <td>True</td>\n <td>6.120788</td>\n <td>1.097892e+10</td>\n <td>1.097892e+10</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>LINESTRING (531170.579 178714.27, 531159.206 1...</td>\n </tr>\n <tr>\n <th>1</th>\n <td>1</td>\n <td>changed</td>\n <td>1164681932</td>\n <td>False</td>\n <td>False</td>\n <td>4.294142</td>\n <td>1.083209e+10</td>\n <td>1.083207e+10</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>LINESTRING (531160.428 178297.072, 531163.684 ...</td>\n </tr>\n <tr>\n <th>2</th>\n <td>2</td>\n <td>changed</td>\n <td>1164726934</td>\n <td>False</td>\n <td>False</td>\n <td>5.494649</td>\n <td>1.083207e+10</td>\n <td>1.083208e+10</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>commercial</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>LINESTRING (531160.428 178297.072, 531163.689 ...</td>\n </tr>\n <tr>\n <th>3</th>\n <td>3</td>\n <td>changed</td>\n <td>[ 605011820, 605011815 ]</td>\n <td>True</td>\n <td>False</td>\n <td>23.615083</td>\n <td>1.266671e+10</td>\n <td>1.020753e+10</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>LINESTRING (531164.932 178197.035, 531164.265 ...</td>\n </tr>\n <tr>\n <th>4</th>\n <td>4</td>\n <td>changed</td>\n <td>1164685671</td>\n <td>False</td>\n <td>True</td>\n <td>8.108433</td>\n <td>1.083209e+10</td>\n <td>1.083209e+10</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>LINESTRING (531160.261 178293.028, 531164.594 ...</td>\n </tr>\n <tr>\n <th>...</th>\n <td>...</td>\n <td>...</td>\n <td>...</td>\n <td>...</td>\n <td>...</td>\n <td>...</td>\n <td>...</td>\n <td>...</td>\n <td>...</td>\n <td>...</td>\n <td>...</td>\n <td>...</td>\n <td>...</td>\n <td>...</td>\n <td>...</td>\n <td>...</td>\n <td>...</td>\n </tr>\n <tr>\n <th>4969</th>\n <td>4969</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>NaN</td>\n <td>NaN</td>\n <td>NaN</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>LINESTRING (532417.268 178117.184, 532416.739 ...</td>\n </tr>\n <tr>\n <th>4970</th>\n <td>4970</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>NaN</td>\n <td>NaN</td>\n <td>NaN</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>LINESTRING (532471.457 178772.048, 532472.578 ...</td>\n </tr>\n <tr>\n <th>4971</th>\n <td>4971</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>NaN</td>\n <td>NaN</td>\n <td>NaN</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>LINESTRING (531197.202 178215.171, 531198.83 1...</td>\n </tr>\n <tr>\n <th>4972</th>\n <td>4972</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>NaN</td>\n <td>NaN</td>\n <td>NaN</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>LINESTRING (531197.759 178216.039, 531198.83 1...</td>\n </tr>\n <tr>\n <th>4973</th>\n <td>4973</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>NaN</td>\n <td>NaN</td>\n <td>NaN</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>LINESTRING (531593.646 178306.008, 531593.304 ...</td>\n </tr>\n </tbody>\n</table>\n<p>4974 rows × 17 columns</p>\n</div>","text/plain":" index _status osmid oneway reversed length \\\n0 0 changed 1182255831 False True 6.120788 \n1 1 changed 1164681932 False False 4.294142 \n2 2 changed 1164726934 False False 5.494649 \n3 3 changed [ 605011820, 605011815 ] True False 23.615083 \n4 4 changed 1164685671 False True 8.108433 \n... ... ... ... ... ... ... \n4969 4969 None None None None NaN \n4970 4970 None None None None NaN \n4971 4971 None None None None NaN \n4972 4972 None None None None NaN \n4973 4973 None None None None NaN \n\n from to service width ref landuse bridge \\\n0 1.097892e+10 1.097892e+10 None None None None None \n1 1.083209e+10 1.083207e+10 None None None None None \n2 1.083207e+10 1.083208e+10 None None None commercial None \n3 1.266671e+10 1.020753e+10 None None None None None \n4 1.083209e+10 1.083209e+10 None None None None None \n... ... ... ... ... ... ... ... \n4969 NaN NaN None None None None None \n4970 NaN NaN None None None None None \n4971 NaN NaN None None None None None \n4972 NaN NaN None None None None None \n4973 NaN NaN None None None None None \n\n tunnel est_width area geometry \n0 None None None LINESTRING (531170.579 178714.27, 531159.206 1... \n1 None None None LINESTRING (531160.428 178297.072, 531163.684 ... \n2 None None None LINESTRING (531160.428 178297.072, 531163.689 ... \n3 None None None LINESTRING (531164.932 178197.035, 531164.265 ... \n4 None None None LINESTRING (531160.261 178293.028, 531164.594 ... \n... ... ... ... ... \n4969 None None None LINESTRING (532417.268 178117.184, 532416.739 ... \n4970 None None None LINESTRING (532471.457 178772.048, 532472.578 ... \n4971 None None None LINESTRING (531197.202 178215.171, 531198.83 1... \n4972 None None None LINESTRING (531197.759 178216.039, 531198.83 1... \n4973 None None None LINESTRING (531593.646 178306.008, 531593.304 ... \n\n[4974 rows x 17 columns]"},"execution_count":5,"metadata":{},"output_type":"execute_result"}],"execution_count":5},{"id":"d259cf94-d3f8-4f61-9845-4eb0867f9ba4","cell_type":"markdown","source":"### Known trouble makers\n\n* see [here](https://github.com/uscuni/neatnet/issues/214#issuecomment-2914566461)","metadata":{}},{"id":"d4f5f9fb-b6e3-47b2-9c3c-1cf97ebacef9","cell_type":"code","source":"known_trouble_features_ix = [\n 605,\n 606,\n 607,\n 608,\n]\nknown_trouble_features = empirical_edges.loc[known_trouble_features_ix].copy()\nknown_trouble_features","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:38.158421Z","iopub.status.busy":"2025-05-31T19:55:38.157442Z","iopub.status.idle":"2025-05-31T19:55:38.175786Z","shell.execute_reply":"2025-05-31T19:55:38.175377Z","shell.execute_reply.started":"2025-05-31T19:55:38.158367Z"},"trusted":true},"outputs":[{"data":{"text/html":"<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>index</th>\n <th>_status</th>\n <th>osmid</th>\n <th>oneway</th>\n <th>reversed</th>\n <th>length</th>\n <th>from</th>\n <th>to</th>\n <th>service</th>\n <th>width</th>\n <th>ref</th>\n <th>landuse</th>\n <th>bridge</th>\n <th>tunnel</th>\n <th>est_width</th>\n <th>area</th>\n <th>geometry</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>605</th>\n <td>605</td>\n <td>changed</td>\n <td>966958053</td>\n <td>False</td>\n <td>True</td>\n <td>116.206106</td>\n <td>8.946109e+09</td>\n <td>8.946109e+09</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>LINESTRING (532386.697 178301.475, 532385.718 ...</td>\n </tr>\n <tr>\n <th>606</th>\n <td>606</td>\n <td>changed</td>\n <td>966958054</td>\n <td>False</td>\n <td>True</td>\n <td>6.955070</td>\n <td>8.946109e+09</td>\n <td>1.150486e+10</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>LINESTRING (532386.697 178301.475, 532387.222 ...</td>\n </tr>\n <tr>\n <th>607</th>\n <td>607</td>\n <td>changed</td>\n <td>966958054</td>\n <td>False</td>\n <td>False</td>\n <td>6.931236</td>\n <td>8.946109e+09</td>\n <td>1.150486e+10</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>LINESTRING (532386.697 178301.475, 532387.952 ...</td>\n </tr>\n <tr>\n <th>608</th>\n <td>608</td>\n <td>changed</td>\n <td>966958054</td>\n <td>False</td>\n <td>False</td>\n <td>116.496631</td>\n <td>1.150486e+10</td>\n <td>1.150486e+10</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>None</td>\n <td>LINESTRING (532392.597 178305.167, 532393.837 ...</td>\n </tr>\n </tbody>\n</table>\n</div>","text/plain":" index _status osmid oneway reversed length from \\\n605 605 changed 966958053 False True 116.206106 8.946109e+09 \n606 606 changed 966958054 False True 6.955070 8.946109e+09 \n607 607 changed 966958054 False False 6.931236 8.946109e+09 \n608 608 changed 966958054 False False 116.496631 1.150486e+10 \n\n to service width ref landuse bridge tunnel est_width area \\\n605 8.946109e+09 None None None None None None None None \n606 1.150486e+10 None None None None None None None None \n607 1.150486e+10 None None None None None None None None \n608 1.150486e+10 None None None None None None None None \n\n geometry \n605 LINESTRING (532386.697 178301.475, 532385.718 ... \n606 LINESTRING (532386.697 178301.475, 532387.222 ... \n607 LINESTRING (532386.697 178301.475, 532387.952 ... \n608 LINESTRING (532392.597 178305.167, 532393.837 ... "},"execution_count":6,"metadata":{},"output_type":"execute_result"}],"execution_count":6},{"id":"f379fce5-b152-4d75-9213-5387f7235bc9","cell_type":"code","source":"known_trouble_features.plot(figsize=(7,7), lw=5, cmap=\"Paired\")","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:38.858330Z","iopub.status.busy":"2025-05-31T19:55:38.857699Z","iopub.status.idle":"2025-05-31T19:55:39.024542Z","shell.execute_reply":"2025-05-31T19:55:39.024240Z","shell.execute_reply.started":"2025-05-31T19:55:38.858279Z"},"trusted":true},"outputs":[{"data":{"text/plain":"<Axes: >"},"execution_count":7,"metadata":{},"output_type":"execute_result"},{"data":{"image/png":"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","text/plain":"<Figure size 700x700 with 1 Axes>"},"metadata":{},"output_type":"display_data"}],"execution_count":7},{"id":"d65cd250-11e0-4325-9a04-2681961598f7","cell_type":"markdown","source":"### Empirical failure\n\n#### directly call `remove_interstitial_nodes()`\n\n* same error as [#214](https://github.com/uscuni/neatnet/issues/214)","metadata":{}},{"id":"538a47eb-9c43-403d-a1c7-9c1b2bae85ff","cell_type":"code","source":"neatnet.remove_interstitial_nodes(known_trouble_features)","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:40.343731Z","iopub.status.busy":"2025-05-31T19:55:40.342994Z","iopub.status.idle":"2025-05-31T19:55:40.513369Z","shell.execute_reply":"2025-05-31T19:55:40.512762Z","shell.execute_reply.started":"2025-05-31T19:55:40.343676Z"},"trusted":true},"outputs":[{"ename":"ValueError","evalue":"operands could not be broadcast together with shapes (7,2) (0,2) ","output_type":"error","traceback":["\u001b[31m---------------------------------------------------------------------------\u001b[39m","\u001b[31mValueError\u001b[39m Traceback (most recent call last)","\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[8]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m \u001b[43mneatnet\u001b[49m\u001b[43m.\u001b[49m\u001b[43mremove_interstitial_nodes\u001b[49m\u001b[43m(\u001b[49m\u001b[43mknown_trouble_features\u001b[49m\u001b[43m)\u001b[49m\n","\u001b[36mFile \u001b[39m\u001b[32m~/github_repos/uscuni/neatnet/neatnet/nodes.py:416\u001b[39m, in \u001b[36mremove_interstitial_nodes\u001b[39m\u001b[34m(gdf, aggfunc, **kwargs)\u001b[39m\n\u001b[32m 414\u001b[39m target_nodes = nodes[node_ix[loop_ix == ix]]\n\u001b[32m 415\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(target_nodes) == \u001b[32m2\u001b[39m:\n\u001b[32m--> \u001b[39m\u001b[32m416\u001b[39m new_sequence = \u001b[43m_rotate_loop_coords\u001b[49m\u001b[43m(\u001b[49m\u001b[43mloop_geom\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mnot_loops\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 417\u001b[39m fixed_loops.append(shapely.LineString(new_sequence))\n\u001b[32m 418\u001b[39m fixed_index.append(ix)\n","\u001b[36mFile \u001b[39m\u001b[32m~/github_repos/uscuni/neatnet/neatnet/nodes.py:449\u001b[39m, in \u001b[36m_rotate_loop_coords\u001b[39m\u001b[34m(loop_geom, not_loops)\u001b[39m\n\u001b[32m 446\u001b[39m mode = mode.iloc[[\u001b[32m0\u001b[39m]]\n\u001b[32m 448\u001b[39m new_start = mode.get_coordinates().values\n\u001b[32m--> \u001b[39m\u001b[32m449\u001b[39m _coords_match = (\u001b[43mloop_coords\u001b[49m\u001b[43m \u001b[49m\u001b[43m==\u001b[49m\u001b[43m \u001b[49m\u001b[43mnew_start\u001b[49m).all(axis=\u001b[32m1\u001b[39m)\n\u001b[32m 450\u001b[39m new_start_idx = np.where(_coords_match)[\u001b[32m0\u001b[39m].squeeze()\n\u001b[32m 452\u001b[39m rolled_coords = np.roll(loop_coords[:-\u001b[32m1\u001b[39m], -new_start_idx, axis=\u001b[32m0\u001b[39m)\n","\u001b[31mValueError\u001b[39m: operands could not be broadcast together with shapes (7,2) (0,2) "]}],"execution_count":8},{"id":"d96f6ccc-c22c-4700-8896-3d71cc32bb67","cell_type":"markdown","source":"#### call `fix_topology()`","metadata":{}},{"id":"adea066b-ebb3-4972-b378-3aaa48136e80","cell_type":"code","source":"neatnet.fix_topology(known_trouble_features)","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:41.956860Z","iopub.status.busy":"2025-05-31T19:55:41.955756Z","iopub.status.idle":"2025-05-31T19:55:42.026921Z","shell.execute_reply":"2025-05-31T19:55:42.026442Z","shell.execute_reply.started":"2025-05-31T19:55:41.956803Z"},"trusted":true},"outputs":[{"ename":"ValueError","evalue":"operands could not be broadcast together with shapes (7,2) (0,2) ","output_type":"error","traceback":["\u001b[31m---------------------------------------------------------------------------\u001b[39m","\u001b[31mValueError\u001b[39m Traceback (most recent call last)","\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[9]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m \u001b[43mneatnet\u001b[49m\u001b[43m.\u001b[49m\u001b[43mfix_topology\u001b[49m\u001b[43m(\u001b[49m\u001b[43mknown_trouble_features\u001b[49m\u001b[43m)\u001b[49m\n","\u001b[36mFile \u001b[39m\u001b[32m~/github_repos/uscuni/neatnet/neatnet/nodes.py:491\u001b[39m, in \u001b[36mfix_topology\u001b[39m\u001b[34m(roads, eps, **kwargs)\u001b[39m\n\u001b[32m 489\u001b[39m roads = roads[~roads.geometry.normalize().duplicated()].copy()\n\u001b[32m 490\u001b[39m roads_w_nodes = induce_nodes(roads, eps=eps)\n\u001b[32m--> \u001b[39m\u001b[32m491\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mremove_interstitial_nodes\u001b[49m\u001b[43m(\u001b[49m\u001b[43mroads_w_nodes\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n","\u001b[36mFile \u001b[39m\u001b[32m~/github_repos/uscuni/neatnet/neatnet/nodes.py:416\u001b[39m, in \u001b[36mremove_interstitial_nodes\u001b[39m\u001b[34m(gdf, aggfunc, **kwargs)\u001b[39m\n\u001b[32m 414\u001b[39m target_nodes = nodes[node_ix[loop_ix == ix]]\n\u001b[32m 415\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(target_nodes) == \u001b[32m2\u001b[39m:\n\u001b[32m--> \u001b[39m\u001b[32m416\u001b[39m new_sequence = \u001b[43m_rotate_loop_coords\u001b[49m\u001b[43m(\u001b[49m\u001b[43mloop_geom\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mnot_loops\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 417\u001b[39m fixed_loops.append(shapely.LineString(new_sequence))\n\u001b[32m 418\u001b[39m fixed_index.append(ix)\n","\u001b[36mFile \u001b[39m\u001b[32m~/github_repos/uscuni/neatnet/neatnet/nodes.py:449\u001b[39m, in \u001b[36m_rotate_loop_coords\u001b[39m\u001b[34m(loop_geom, not_loops)\u001b[39m\n\u001b[32m 446\u001b[39m mode = mode.iloc[[\u001b[32m0\u001b[39m]]\n\u001b[32m 448\u001b[39m new_start = mode.get_coordinates().values\n\u001b[32m--> \u001b[39m\u001b[32m449\u001b[39m _coords_match = (\u001b[43mloop_coords\u001b[49m\u001b[43m \u001b[49m\u001b[43m==\u001b[49m\u001b[43m \u001b[49m\u001b[43mnew_start\u001b[49m).all(axis=\u001b[32m1\u001b[39m)\n\u001b[32m 450\u001b[39m new_start_idx = np.where(_coords_match)[\u001b[32m0\u001b[39m].squeeze()\n\u001b[32m 452\u001b[39m rolled_coords = np.roll(loop_coords[:-\u001b[32m1\u001b[39m], -new_start_idx, axis=\u001b[32m0\u001b[39m)\n","\u001b[31mValueError\u001b[39m: operands could not be broadcast together with shapes (7,2) (0,2) "]}],"execution_count":9},{"id":"95a6bdd2-83cc-4a68-80c4-d4496cb2e89c","cell_type":"markdown","source":"-----------------------------------------------------\n\n## Synthetic\n\n### Mimic empirical features","metadata":{}},{"id":"2847b2de-6500-40aa-a8df-70342684efab","cell_type":"code","source":"# left edge loop points\np01, p02, p03 = Point(1, 1), Point(1, 3), Point(2, 2)\n\n# right edge loop points\np04, p05, p06 = Point(7, 1), Point(7, 3), Point(6, 2)\n\n# two middle edges points\np07, p08, p09, p10 = Point(3, 3), Point(5, 3), Point(5, 1), Point(3, 1)\n\n# left and right loops\nloop1, loop2 = LineString((p01, p02, p03, p01)), LineString((p04, p05, p06, p04))\n\n# lower & upper middle edges\nmid1, mid2 = LineString((p03, p07, p08, p06)), LineString((p06, p09, p10, p03))\n\nsynthetic_edges = geopandas.GeoDataFrame(geometry=[loop1, loop2, mid1, mid2])\nsynthetic_edges","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:43.161765Z","iopub.status.busy":"2025-05-31T19:55:43.161178Z","iopub.status.idle":"2025-05-31T19:55:43.178007Z","shell.execute_reply":"2025-05-31T19:55:43.177420Z","shell.execute_reply.started":"2025-05-31T19:55:43.161718Z"},"trusted":true},"outputs":[{"data":{"text/html":"<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>geometry</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>LINESTRING (1 1, 1 3, 2 2, 1 1)</td>\n </tr>\n <tr>\n <th>1</th>\n <td>LINESTRING (7 1, 7 3, 6 2, 7 1)</td>\n </tr>\n <tr>\n <th>2</th>\n <td>LINESTRING (2 2, 3 3, 5 3, 6 2)</td>\n </tr>\n <tr>\n <th>3</th>\n <td>LINESTRING (6 2, 5 1, 3 1, 2 2)</td>\n </tr>\n </tbody>\n</table>\n</div>","text/plain":" geometry\n0 LINESTRING (1 1, 1 3, 2 2, 1 1)\n1 LINESTRING (7 1, 7 3, 6 2, 7 1)\n2 LINESTRING (2 2, 3 3, 5 3, 6 2)\n3 LINESTRING (6 2, 5 1, 3 1, 2 2)"},"execution_count":10,"metadata":{},"output_type":"execute_result"}],"execution_count":10},{"id":"53ebf988-e919-4820-9a8a-e25173a5f4f1","cell_type":"code","source":"synthetic_edges.plot(cmap=\"Paired\", lw=5)","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:43.753264Z","iopub.status.busy":"2025-05-31T19:55:43.752571Z","iopub.status.idle":"2025-05-31T19:55:43.808664Z","shell.execute_reply":"2025-05-31T19:55:43.808418Z","shell.execute_reply.started":"2025-05-31T19:55:43.753211Z"},"trusted":true},"outputs":[{"data":{"text/plain":"<Axes: >"},"execution_count":11,"metadata":{},"output_type":"execute_result"},{"data":{"image/png":"iVBORw0KGgoAAAANSUhEUgAAAiMAAADRCAYAAAAe77KKAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAIINJREFUeJzt3X1wE/e97/GPbNkyD7aIuX48lsEJBIgJD8U5iRMISd3CNakLEyZt77SNm7TMdWNIGg8zOc6dOW0naUyn6Qyh9JiSQ534MkB6j4GY8twb25QcQzGBhsODCzce7Bg7BBIk2yEytvf+QSQQluRdWdrfb3c/r5n9Q6td6WuFoDe7K9mmKIoCIiIiIkHiRA9ARERE1sYYISIiIqEYI0RERCQUY4SIiIiEYowQERGRUIwRIiIiEooxQkREREIxRoiIiEgou+gB1BgaGsKlS5eQnJwMm80mehwiIiJSQVEU9PT0IDs7G3FxoY9/GCJGLl26BJfLJXoMIiIiikBHRwdycnJC3m+IGElOTgZw84dJSUkRPA0RERGp4fF44HK5/O/joRgiRnynZlJSUhgjREREBjPSJRaaLmCtrq7GrFmz/FFQWFiIvXv3ht2nqakJ8+bNQ1JSEu6++25s2LBBy1MSGZKiKFy4xGwhMhtNR0ZycnKwZs0aTJkyBQDw9ttvY+nSpThx4gTy8/OHbd/W1oYlS5ZgxYoV2Lx5M95//30899xzSEtLw/Lly6PzE0So7Wofzl7uxfUbg0hJsmPuPznx38Y5hM5Extd37To6zlxG3+fXMTTENw2KPntiPCZkjIfrvgzYE+NFj0MGpigKlHPnMPTh34Evv4QtMxNxX5sHW1qa7rPYlFFmdmpqKn7zm9/gxz/+8bD7XnrpJdTX1+Ps2bP+dWVlZfj73/+O5uZm1c/h8XjgdDrhdrujcprmo6t9ONr+ecA6G4AHJ92FvNRxo358sqZrn/TiQsvHUBghpAPHuERMfzgXiUkJokchA1KGhjDU1AjlwoXAOxwOxC9dBpvTGZXnUfv+HfH3jAwODmLbtm3o6+tDYWFh0G2am5uxaNGigHWLFy9GS0sLbty4EfKxvV4vPB5PwBJNZz7pGbZOAXD04udo+6wvqs9F1sAQIb15+/px7j/b0f9l6L9LiYIJGSIA4PVi6NzZ4etjTHOMnDp1CuPHj4fD4UBZWRl27NiB++67L+i23d3dyMjICFiXkZGBgYEBXLlyJeRzVFVVwel0+pdofqy3f3AIPd6BoPcxSCgSDBEShUFCWoUNEd82n36q40Q3aY6RadOm4eTJkzhy5Ah++tOforS0FGfOnAm5/Z1X0PrOCoW7srayshJut9u/dHR0aB0zpJHOSjFISAuGCInGICG11IQIAGBwSJ+BbqP5o72JiYn+C1gLCgpw7NgxvPHGG/jDH/4wbNvMzEx0d3cHrLt8+TLsdjsmTpwY8jkcDgccDnEXk/qCBACvIaGQGCIkC1+Q8BoSCkV1iAgy6u8ZURQFXq836H2FhYXYtWtXwLoDBw6goKAACQly/w/DIKFw1IZIvD3u5tXRRKOkDCphP6HFIKFQZA8RQGOMvPzyyyguLobL5UJPTw+2bduGxsZG7Nu3D8DN0yudnZ2ora0FcPOTM+vXr0dFRQVWrFiB5uZmbNq0CVu3bo3+TxIDDBIKRm2IpOfdhdz8DP4+JYqKgf5BtDZfxBee4P/4AxgkNJwRQgTQeM3IJ598gh/+8IeYNm0aioqKcPToUezbtw/f/OY3AQBdXV1ob2/3b5+Xl4c9e/agsbERc+bMwSuvvIJ169YJ/44RLXgNCd2OIUKi2BPjMa1wEsamhD+FzWtIyMcoIQJE4XtG9BDN7xnxDgxi+6kuzfvxe0iIIUIyUHOEBOD3kFjdqEIkPQP2pUujMkfMv2fEaniExNoYIiQLHiGhkRjpiIgPY+Q2I719MEisiSFCsmGQUCiqQ0Syv6cYI7cZlxiP+7PCnwZikFgLQ4RkxSChO6kOkYQExD0yX5+hVGKM3GFmZgqDhAAwREh+DBLy0RIi8cXFsN3x7eiiMUaCYJAQQ4SMgkFC2kMkU5/BNGCMhMAgsS6GCBkNg8S6zBAiAGMkLAaJ9TBEyKgYJNZjlhABGCMjYpBYB0OEjI5BYh1mChGAMaIKg8T8GCJkFgwS8zNbiACMEdUYJObFECGzYZCYlxlDBGCMaMIgMR+GCJkVg8R8zBoiAGNEMwaJeTBEyOwYJOZh5hABGCMRYZAYH0OErIJBYnxmDxGAMRIxBolxMUTIahgkxmWFEAEYI6PCIDEehghZFYPEeKwSIgBjZNQYJMbBECGrY5AYh5VCBGCMRAWDRH4MEaKbGCTys1qIAIyRqGGQyIshQhSIQSIvK4YIwBiJKgaJfBgiRMExSORj1RABGCNRxyCRB0OEKDwGiTysHCIAYyQmGCTiMUSI1GGQiGf1EAEYIzHDIBGHIUKkDYNEHIbITYyRGGKQ6I8hQhQZBon+GCK3MEZijEGiH4YI0egwSPTDEAnEGNEBgyT2GCJE0cEgiT2GyHCMEZ0wSGKHIUIUXQyS2GGIBMcY0RGDJPoYIkSxwSCJPoZIaJpipKqqCg888ACSk5ORnp6OZcuWobW1New+jY2NsNlsw5Zz586NanCjYpBED0OEKLYYJNHDEAlPU4w0NTWhvLwcR44cwcGDBzEwMIBFixahr2/kN83W1lZ0dXX5l6lTp0Y8tNExSEaPIUKkDwbJ6DFERmbXsvG+ffsCbtfU1CA9PR3Hjx/Ho48+Gnbf9PR0TJgwQfOAZjUz82aMnOryhNzGFyQAkJc6To+xDIEhQqQvX5C0Nl/EFx5vyO18QTL94VwkJiXoOKG8GCLqjOqaEbfbDQBITU0dcdu5c+ciKysLRUVFaGhoCLut1+uFx+MJWMyIR0i0Y4gQicEjJNoxRNSLOEYURUFFRQXmz5+PmTNnhtwuKysLGzduRF1dHbZv345p06ahqKgIhw4dCrlPVVUVnE6nf3G5XJGOKT0GiXoMESKxGCTqMUS0sSmKEv5v9hDKy8uxe/duHD58GDk5OZr2LSkpgc1mQ319fdD7vV4vvN5bhwI9Hg9cLhfcbjdSUsK/cY/EOzCI7ae6gt43PjEeJflZo3r8SP1XtyfsKRsAsAF4cNJdljxlwxAhksdA/+CIp2wAwDEu0ZKnbIwQIspnn2Gw7j+C35meAfvSpVF5Ho/HA6fTOeL7d0RHRlatWoX6+no0NDRoDhEAeOihh3D+/PmQ9zscDqSkpAQsZscjJKExRIjkwiMkoRkhRGSkKUYURcHKlSuxfft2vPfee8jLy4voSU+cOIGsLDFHIGTGIBmOIUIkJwbJcAyRyGn6NE15eTm2bNmCd999F8nJyeju7gYAOJ1OjBkzBgBQWVmJzs5O1NbWAgDWrl2LyZMnIz8/H/39/di8eTPq6upQV1cX5R/FHPgpm1sYIkRy46dsbmGIjI6mIyPV1dVwu9147LHHkJWV5V/eeecd/zZdXV1ob2/33+7v78fq1asxa9YsLFiwAIcPH8bu3bvx5JNPRu+nMBkeIWGIEBkFj5AwRKIh4gtY9aT2Ahg1ZL2ANRirXtTKECEyHqte1GrUEDHFBaykDyseIWGIEBmTFY+QGDVEZMQYkZyVgoQhQmRsVgoShkh0MUYMwApBwhAhMgcrBAlDJPoYIwZh5iBhiBCZi5mDhCESG4wRAzFjkDBEiMzJjEHCEIkdxojBmClIGCJE5mamIGGIxBZjxIDMECQMESJrMEOQMERijzFiUEYOEoYIkbUYOUgYIvpgjBiYEYOEIUJkTUYMEoaIfhgjBmekIGGIEFmbkYKEIaIvxogJGCFIGCJEBBgjSBgi+mOMmITMQcIQIaLbyRwkDBExGCMmImOQMESIKBgZg4QhIg5jxGRkChKGCBGFI1OQMETEYoyYkAxBwhAhIjVkCBKGiHiMEZMSGSQMESLSQmSQMETkwBgxMRFBwhAhokiICBKGiDwYIyanZ5AwRIhoNPQMEoaIXBgjFqBHkDBEiCga9AgShoh8GCMWEcsgYYgQUTTFMkgYInJijFhILIKEIUJEsRCLIGGIyIsxYjHRDBKGCBHFUjSDhCEiN8aIBUUjSBgiRKSHaAQJQ0R+jBGLGk2QMESISE+jCRKGiDEwRiwskiBhiBCRCJEECUPEOOyiByCxZmbejJFTXZ6Q2/iCpP/z6+g5d4UhQkRC+IKktfkivvB4Q253M0guYqryMRI+YogYgaYjI1VVVXjggQeQnJyM9PR0LFu2DK2trSPu19TUhHnz5iEpKQl33303NmzYEPHAFH1qjpCMuT4A95lPGSJEJJT6IyQ3cN6TjBtxiaE3YohIQ1OMNDU1oby8HEeOHMHBgwcxMDCARYsWoa8v9Kcu2trasGTJEixYsAAnTpzAyy+/jOeffx51dXWjHp6iJ1yQjL0+gKyr1zFSXjBEiEgPqoPEPhbnU+8PHiQMEaloOk2zb9++gNs1NTVIT0/H8ePH8eijjwbdZ8OGDcjNzcXatWsBADNmzEBLSwtef/11LF++PLKpKSZCnbIZ4x0ICJEv2poAAGPzFvrXMUSISE/BTtkoQ4PoOfk2xk7577CnZAMA+uOTcN0+Fgn9/bd2ZohIZ1QXsLrdbgBAampqyG2am5uxaNGigHWLFy9GS0sLbtyI/q+CptEJdoTkqtOBa+MTANwMEffR38F99Hf+KGGIEJEItx8hUYYGce3IOvS1/hlX3/tXDHguwaYMIe/aGaT0X7u1E0NEShHHiKIoqKiowPz58zFz5syQ23V3dyMjIyNgXUZGBgYGBnDlypWg+3i9Xng8noCF9DMzMwWT7xp7a4XNhitOB650HYb76O8AZQhQhuA++jsk9LUwRIhIGHtiPO59MAe9x3+PLy/+FQAwdP0zXH3vX5HZeQhO7+cB28ctXMgQkVDEMbJy5Up8+OGH2Lp164jb3vlGpShK0PU+VVVVcDqd/sXlckU6JkXgkvs62q99EbAu/sz/RX/T2psh4qMMoX3XGnz8/i59ByQi+ooyNIgP//1/ofdCY8D6oeuf4fTRTej9IjBGhv52DEqY6xxJjIhiZNWqVaivr0dDQwNycnLCbpuZmYnu7u6AdZcvX4bdbsfEiROD7lNZWQm32+1fOjo6IhmTInDJfR1/bbuK2z80E3/6L3Ds/Q1st4eIjzKEE9WV6Dhcr9+QRES4GSIf/Nu/oPM//xz0fm9/H46e+D+BQeJxY/DPf2aQSEZTjCiKgpUrV2L79u147733kJeXN+I+hYWFOHjwYMC6AwcOoKCgAAkJCUH3cTgcSElJCVgo9oKFCADE9XwaPER8GCREpLORQsRnYLAfN25cD1zJIJGOphgpLy/H5s2bsWXLFiQnJ6O7uxvd3d24fv3Wf+jKyko8/fTT/ttlZWW4ePEiKioqcPbsWfzxj3/Epk2bsHr16uj9FDRqoUIEAG489D/QP/9H4R+AQUJEOlEbIvHxCfjn2U/iLmf28DsZJFLRFCPV1dVwu9147LHHkJWV5V/eeecd/zZdXV1ob2/3387Ly8OePXvQ2NiIOXPm4JVXXsG6dev4sV6JhAsRnxuF30fK4v8Z/oEYJEQUY6pDxDEW/7zgmeAh4sMgkYam7xnxXXgazltvvTVs3cKFC/HBBx9oeSrSiZoQAYB708bja0+/gPPOJJz70xuhN/wqSADANf/bUZyUiKxOdYgkjUXhv/w77sqdgcE9u4GrV0Nv/FWQxH/rW7CNGxfliUkt/qI8C9MUIv/khM1mw73LyjD9Oy+E34FHSIgoyrSGSOq9c2FLSkL8kieAEB+W8OMREuEYIxYVSYj41zFIiEhHkYSID4PEGBgjFjSaEPHfxyAhIh2MJkR8GCTyY4xYTDRCxL8Ng4SIYigaIeLDIJEbY8RCohki/m0ZJEQUA9EMER8GibwYIxYRixDx78MgIaIoikWI+DBI5MQYsYBYhoh/XwYJEUVBLEPEh0EiH8aIyekRIv7HYJAQ0SjoESI+DBK5MEZMTM8Q8T8Wg4SIIqBniPgwSOTBGDEpESHif0wGCRFpICJEfBgkcmCMmJDIEPE/NoOEiFQQGSI+DBLxGCMmI0OI+J+DQUJEYcgQIj4MErEYIyYiU4j4n4tBQkRByBQiPgwScRgjJiFjiPifk0FCRLeRMUR8GCRiMEZMQOYQ8T83g4SIIHeI+DBI9McYMTgjhIh/BgYJkaUZIUR8GCT6YowYmJFCxD8Lg4TIkowUIj4MEv0wRgzKiCHiwyAhshYjhogPg0QfjBEDMnKI+DBIiKzByCHiwyCJPcaIwZghRHwYJETmZoYQ8WGQxBZjxEDMFCI+DBIiczJTiPgwSGKHMWIQZgwRHwYJkbmYMUR8GCSxwRgxADOHiA+DhMgczBwiPgyS6GOMSM4KIeLDICEyNiuEiA+DJLoYIxKzUoj4MEiIjMlKIeLDIIkexoikrBgiPgwSImOxYoj4MEiigzEiISuHiA+DhMgYrBwiPgyS0dMcI4cOHUJJSQmys7Nhs9mwc+fOsNs3NjbCZrMNW86dOxfpzKbGELmFQUIkN4bILQyS0dEcI319fZg9ezbWr1+vab/W1lZ0dXX5l6lTp2p9atNjiAzHICGSE0NkOAZJ5OxadyguLkZxcbHmJ0pPT8eECRM072cVDJHQ7l1WBgA496c3Qm/0VZAAgGv+t/UYi8iyGCKh+YJkcM9u4OrV0Bt+FSTx3/oWbOPG6TegpHS7ZmTu3LnIyspCUVERGhoawm7r9Xrh8XgCFjNjiIyMR0iI5MAQGRmPkGgX8xjJysrCxo0bUVdXh+3bt2PatGkoKirCoUOHQu5TVVUFp9PpX1wuV6zHFIYhoh6DhEgshoh6DBJtbIqijPA2GGZnmw07duzAsmXLNO1XUlICm82G+vrgbxherxder9d/2+PxwOVywe12IyUlJdJxbz72wCC2n+oKet/4xHiU5GeN6vG1YIhE5h87N4Q/ZQMAtjjM/WkVT9kQRQlDJDLKl1+OfMoGAFKcup6yUT77DIN1/xH8zvQM2JcujcrzeDweOJ3OEd+/hXy096GHHsL58+dD3u9wOJCSkhKwmA1DJHI8QkKkL4ZI5HiERB0hMXLixAlkZel3BEI2DJHRY5AQ6YMhMnoMkpFp/jRNb28vLly44L/d1taGkydPIjU1Fbm5uaisrERnZydqa2sBAGvXrsXkyZORn5+P/v5+bN68GXV1dairq4veT2EgDJHo4adsiGKLIRI9/JRNeJpjpKWlBY8//rj/dkVFBQCgtLQUb731Frq6utDe3u6/v7+/H6tXr0ZnZyfGjBmD/Px87N69G0uWLInC+MbCEIk+BglRbDBEoo9BEtqoLmDVi9oLYNQQdQErQyS2eFErUfQwRGJLhotaeQGrBTFEYo/XkBBFB0Mk9ngNyXCMkRhjiOiHQUI0OgwR/TBIAjFGYoghoj8GCVFkGCL6Y5DcwhiJEYaIOAwSIm0YIuIwSG5ijMQAQ0Q8BgmROgwR8RgkjJGoY4jIg0FCFB5DRB5WDxLGSBQxROTDICEKjiEiHysHCWMkShgi8mKQEAViiMjLqkHCGIkChoj8GCRENzFE5GfFIGGMjBJDxDgYJGR1DBHjsFqQMEZGgSFiPAwSsiqGiPFYKUgYIxFiiBgXg4SshiFiXFYJEsZIBBgixscgIatgiBifFYKEMaIRQ8Q8GCRkdgwR8zB7kDBGNGCImA+DhMyKIWI+Zg4SxohKDBHzYpCQ2TBEzMusQcIYUYEhYn4MEjILhoj5mTFIGCMjYIhYB4OEjI4hYh1mCxLGSBgMEethkJBRMUSsx0xBwhgJgSFiXQwSMhqGiHWZJUgYI0EwRIhBQkbBECEzBAlj5A4MEfJhkJDsGCLkozlIvvhCn8FUYozcprd/kCFCARgkJCuGCN1JS5AM7d2jz1AqMUbuwBChOzFISDYMEQpFdZBIhjGiAUPEuhgkJAuGCI3EiEHCGFGJIUIMEhKNIUJqGS1INMfIoUOHUFJSguzsbNhsNuzcuXPEfZqamjBv3jwkJSXh7rvvxoYNGyKZVRiGCPkwSEgUhghpZaQgsWvdoa+vD7Nnz8YzzzyD5cuXj7h9W1sblixZghUrVmDz5s14//338dxzzyEtLU3V/qIxROhO9y4rAwCc+9MboTf6Kkg+/ms9bHE8AEmj5/V8Bnfb6bDbMEToTr4gGdyzG7h6VfQ4IWmOkeLiYhQXF6vefsOGDcjNzcXatWsBADNmzEBLSwtef/116WOEIUKhqA2ST0+9r9NEZHUMEQrFCEES83+yNTc3Y9GiRQHrFi9ejJaWFty4cSPWTx8xhgiNRNUpGyIdMERoJLKfsol5jHR3dyMjIyNgXUZGBgYGBnDlypWg+3i9Xng8noAlWmywIW1cItLGJSIlKfiBIYYIqcUgIdEYIqTWiEGSkQFkZMI2MVXfwRDBaZpI3PmmrihK0PU+VVVV+OUvfxmTWRLtcfjGven+296BITRc+BSfX795lIYhQlqpOmVDFAMMEdIq2CkbW/5MxBUWCn3fi/mRkczMTHR3dwesu3z5Mux2OyaGqLPKykq43W7/0tHREbP5HPY4PD4lDXeNSWCIUMR4hIT0xhChSN1+hESGEAF0ODJSWFiIXbt2Baw7cOAACgoKkJCQEHQfh8MBh8MR69FuPZ89DkVT02CPswn/D0LGde+yMiRNSMN//e81GLjeK3ocMrHknCn42nO/hnPyfaJHIYOyJSUhvuTbgN0uxfue5hjp7e3FhQsX/Lfb2tpw8uRJpKamIjc3F5WVlejs7ERtbS0AoKysDOvXr0dFRQVWrFiB5uZmbNq0CVu3bo3eTxEFCfH8+CWNXu5jy5EzvwQ9H/8/DHwp1y+iInNIuisdY9NzpHgDIWOzhTggIILmGGlpacHjjz/uv11RUQEAKC0txVtvvYWuri60t7f778/Ly8OePXvw4osv4ve//z2ys7Oxbt066T/WSxSpOHsinJNniB6DiMgwbIrvalKJeTweOJ1OuN1upKSkiB6HiIiIVFD7/q3Lp2lGy9dL0fyILxEREcWW7317pOMehoiRnp4eAIDL5RI8CREREWnV09MDp9MZ8n5DnKYZGhrCpUuXkJycHNWLtjweD1wuFzo6Onj6RwW+XurxtVKPr5V6fK3U42ulXixfK0VR0NPTg+zsbMSF+T1dhjgyEhcXh5ycnJg9fkpKCv+wasDXSz2+VurxtVKPr5V6fK3Ui9VrFe6IiA8/z0pERERCMUaIiIhIKEvHiMPhwM9//nNdv+3VyPh6qcfXSj2+VurxtVKPr5V6MrxWhriAlYiIiMzL0kdGiIiISDzGCBEREQnFGCEiIiKhGCNEREQklGVj5NChQygpKUF2djZsNht27twpeiQpVVVV4YEHHkBycjLS09OxbNkytLa2ih5LStXV1Zg1a5b/i4MKCwuxd+9e0WMZQlVVFWw2G372s5+JHkVKv/jFL2Cz2QKWzMxM0WNJq7OzEz/4wQ8wceJEjB07FnPmzMHx48dFjyWdyZMnD/tzZbPZUF5ervsslo2Rvr4+zJ49G+vXrxc9itSamppQXl6OI0eO4ODBgxgYGMCiRYvQ19cnejTp5OTkYM2aNWhpaUFLSwu+/vWvY+nSpTh9+rTo0aR27NgxbNy4EbNmzRI9itTy8/PR1dXlX06dOiV6JCl9/vnneOSRR5CQkIC9e/fizJkz+O1vf4sJEyaIHk06x44dC/gzdfDgQQDAU089pfsshvg6+FgoLi5GcXGx6DGkt2/fvoDbNTU1SE9Px/Hjx/Hoo48KmkpOJSUlAbd/9atfobq6GkeOHEF+fr6gqeTW29uL73//+3jzzTfx6quvih5Hana7nUdDVPj1r38Nl8uFmpoa/7rJkyeLG0hiaWlpAbfXrFmDe+65BwsXLtR9FsseGaHIuN1uAEBqaqrgSeQ2ODiIbdu2oa+vD4WFhaLHkVZ5eTmeeOIJfOMb3xA9ivTOnz+P7Oxs5OXl4Xvf+x4++ugj0SNJqb6+HgUFBXjqqaeQnp6OuXPn4s033xQ9lvT6+/uxefNmPPvss1H9hbRqMUZINUVRUFFRgfnz52PmzJmix5HSqVOnMH78eDgcDpSVlWHHjh247777RI8lpW3btuGDDz5AVVWV6FGk9+CDD6K2thb79+/Hm2++ie7ubjz88MO4evWq6NGk89FHH6G6uhpTp07F/v37UVZWhueffx61tbWiR5Pazp07ce3aNfzoRz8S8vyWPU1D2q1cuRIffvghDh8+LHoUaU2bNg0nT57EtWvXUFdXh9LSUjQ1NTFI7tDR0YEXXngBBw4cQFJSkuhxpHf7KeX7778fhYWFuOeee/D222+joqJC4GTyGRoaQkFBAV577TUAwNy5c3H69GlUV1fj6aefFjydvDZt2oTi4mJkZ2cLeX4eGSFVVq1ahfr6ejQ0NCAnJ0f0ONJKTEzElClTUFBQgKqqKsyePRtvvPGG6LGkc/z4cVy+fBnz5s2D3W6H3W5HU1MT1q1bB7vdjsHBQdEjSm3cuHG4//77cf78edGjSCcrK2tY/M+YMQPt7e2CJpLfxYsX8Ze//AU/+clPhM3AIyMUlqIoWLVqFXbs2IHGxkbk5eWJHslQFEWB1+sVPYZ0ioqKhn0a5JlnnsH06dPx0ksvIT4+XtBkxuD1enH27FksWLBA9CjSeeSRR4Z9/cA//vEPTJo0SdBE8vN9MOGJJ54QNoNlY6S3txcXLlzw325ra8PJkyeRmpqK3NxcgZPJpby8HFu2bMG7776L5ORkdHd3AwCcTifGjBkjeDq5vPzyyyguLobL5UJPTw+2bduGxsbGYZ9IIiA5OXnYdUfjxo3DxIkTeT1SEKtXr0ZJSQlyc3Nx+fJlvPrqq/B4PCgtLRU9mnRefPFFPPzww3jttdfwne98B3/729+wceNGbNy4UfRoUhoaGkJNTQ1KS0thtwtMAsWiGhoaFADDltLSUtGjSSXYawRAqampET2adJ599lll0qRJSmJiopKWlqYUFRUpBw4cED2WYSxcuFB54YUXRI8hpe9+97tKVlaWkpCQoGRnZytPPvmkcvr0adFjSWvXrl3KzJkzFYfDoUyfPl3ZuHGj6JGktX//fgWA0traKnQOm6IoipgMIiIiIuIFrERERCQYY4SIiIiEYowQERGRUIwRIiIiEooxQkREREIxRoiIiEgoxggREREJxRghIiIioRgjREREJBRjhIiIiIRijBAREZFQjBEiIiIS6v8D9WmPJXHl6ucAAAAASUVORK5CYII=","text/plain":"<Figure size 640x480 with 1 Axes>"},"metadata":{},"output_type":"display_data"}],"execution_count":11},{"id":"25d5020e-ed62-4c45-b9b4-6a7aa8119ee5","cell_type":"markdown","source":"### Synthetic failure\n\n#### directly call `remove_interstitial_nodes()`","metadata":{}},{"id":"af916a7c-a053-4f9e-97fc-9abe482cafa7","cell_type":"code","source":"neatnet.remove_interstitial_nodes(synthetic_edges)","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:44.973617Z","iopub.status.busy":"2025-05-31T19:55:44.973063Z","iopub.status.idle":"2025-05-31T19:55:45.028444Z","shell.execute_reply":"2025-05-31T19:55:45.027968Z","shell.execute_reply.started":"2025-05-31T19:55:44.973575Z"},"trusted":true},"outputs":[{"ename":"ValueError","evalue":"operands could not be broadcast together with shapes (4,2) (0,2) ","output_type":"error","traceback":["\u001b[31m---------------------------------------------------------------------------\u001b[39m","\u001b[31mValueError\u001b[39m Traceback (most recent call last)","\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[12]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m \u001b[43mneatnet\u001b[49m\u001b[43m.\u001b[49m\u001b[43mremove_interstitial_nodes\u001b[49m\u001b[43m(\u001b[49m\u001b[43msynthetic_edges\u001b[49m\u001b[43m)\u001b[49m\n","\u001b[36mFile \u001b[39m\u001b[32m~/github_repos/uscuni/neatnet/neatnet/nodes.py:416\u001b[39m, in \u001b[36mremove_interstitial_nodes\u001b[39m\u001b[34m(gdf, aggfunc, **kwargs)\u001b[39m\n\u001b[32m 414\u001b[39m target_nodes = nodes[node_ix[loop_ix == ix]]\n\u001b[32m 415\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(target_nodes) == \u001b[32m2\u001b[39m:\n\u001b[32m--> \u001b[39m\u001b[32m416\u001b[39m new_sequence = \u001b[43m_rotate_loop_coords\u001b[49m\u001b[43m(\u001b[49m\u001b[43mloop_geom\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mnot_loops\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 417\u001b[39m fixed_loops.append(shapely.LineString(new_sequence))\n\u001b[32m 418\u001b[39m fixed_index.append(ix)\n","\u001b[36mFile \u001b[39m\u001b[32m~/github_repos/uscuni/neatnet/neatnet/nodes.py:449\u001b[39m, in \u001b[36m_rotate_loop_coords\u001b[39m\u001b[34m(loop_geom, not_loops)\u001b[39m\n\u001b[32m 446\u001b[39m mode = mode.iloc[[\u001b[32m0\u001b[39m]]\n\u001b[32m 448\u001b[39m new_start = mode.get_coordinates().values\n\u001b[32m--> \u001b[39m\u001b[32m449\u001b[39m _coords_match = (\u001b[43mloop_coords\u001b[49m\u001b[43m \u001b[49m\u001b[43m==\u001b[49m\u001b[43m \u001b[49m\u001b[43mnew_start\u001b[49m).all(axis=\u001b[32m1\u001b[39m)\n\u001b[32m 450\u001b[39m new_start_idx = np.where(_coords_match)[\u001b[32m0\u001b[39m].squeeze()\n\u001b[32m 452\u001b[39m rolled_coords = np.roll(loop_coords[:-\u001b[32m1\u001b[39m], -new_start_idx, axis=\u001b[32m0\u001b[39m)\n","\u001b[31mValueError\u001b[39m: operands could not be broadcast together with shapes (4,2) (0,2) "]}],"execution_count":12},{"id":"a4c8ca08-fa35-4d0a-b77d-7db437ba63f9","cell_type":"markdown","source":"### Synthetic success\n\n#### call `fix_topology()`","metadata":{}},{"id":"ab1d5469-44be-483c-9309-03cc225b5e56","cell_type":"code","source":"fixed_topology = neatnet.fix_topology(synthetic_edges)\nfixed_topology","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:45.954699Z","iopub.status.busy":"2025-05-31T19:55:45.954294Z","iopub.status.idle":"2025-05-31T19:55:45.985273Z","shell.execute_reply":"2025-05-31T19:55:45.984980Z","shell.execute_reply.started":"2025-05-31T19:55:45.954674Z"},"trusted":true},"outputs":[{"data":{"text/html":"<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>geometry</th>\n <th>_status</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>LINESTRING (2 2, 1 1, 1 3, 2 2)</td>\n <td>changed</td>\n </tr>\n <tr>\n <th>1</th>\n <td>LINESTRING (6 2, 7 1, 7 3, 6 2)</td>\n <td>changed</td>\n </tr>\n <tr>\n <th>2</th>\n <td>LINESTRING (2 2, 3 3, 5 3, 6 2)</td>\n <td>None</td>\n </tr>\n <tr>\n <th>3</th>\n <td>LINESTRING (6 2, 5 1, 3 1, 2 2)</td>\n <td>None</td>\n </tr>\n </tbody>\n</table>\n</div>","text/plain":" geometry _status\n0 LINESTRING (2 2, 1 1, 1 3, 2 2) changed\n1 LINESTRING (6 2, 7 1, 7 3, 6 2) changed\n2 LINESTRING (2 2, 3 3, 5 3, 6 2) None\n3 LINESTRING (6 2, 5 1, 3 1, 2 2) None"},"execution_count":13,"metadata":{},"output_type":"execute_result"}],"execution_count":13},{"id":"413cc2df-0c07-46f3-8b7f-863bcf8c449a","cell_type":"code","source":"fixed_topology.plot(cmap=\"Paired\", lw=5)","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:46.472011Z","iopub.status.busy":"2025-05-31T19:55:46.471326Z","iopub.status.idle":"2025-05-31T19:55:46.526030Z","shell.execute_reply":"2025-05-31T19:55:46.525766Z","shell.execute_reply.started":"2025-05-31T19:55:46.471959Z"},"trusted":true},"outputs":[{"data":{"text/plain":"<Axes: >"},"execution_count":14,"metadata":{},"output_type":"execute_result"},{"data":{"image/png":"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","text/plain":"<Figure size 640x480 with 1 Axes>"},"metadata":{},"output_type":"display_data"}],"execution_count":14},{"id":"d72ee505-e60d-4f45-a969-bbc66ed9932b","cell_type":"markdown","source":"### Altered cases\n\n#### 0 middle edges","metadata":{}},{"id":"e4f9d1f5-76e6-42e0-a499-cc7e43e79c7b","cell_type":"code","source":"neatnet.remove_interstitial_nodes(\n geopandas.GeoDataFrame(geometry=[loop1, loop2])\n)","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:47.550740Z","iopub.status.busy":"2025-05-31T19:55:47.550286Z","iopub.status.idle":"2025-05-31T19:55:47.566398Z","shell.execute_reply":"2025-05-31T19:55:47.566025Z","shell.execute_reply.started":"2025-05-31T19:55:47.550714Z"},"trusted":true},"outputs":[{"data":{"text/html":"<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>geometry</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>LINESTRING (1 1, 1 3, 2 2, 1 1)</td>\n </tr>\n <tr>\n <th>1</th>\n <td>LINESTRING (7 1, 7 3, 6 2, 7 1)</td>\n </tr>\n </tbody>\n</table>\n</div>","text/plain":" geometry\n0 LINESTRING (1 1, 1 3, 2 2, 1 1)\n1 LINESTRING (7 1, 7 3, 6 2, 7 1)"},"execution_count":15,"metadata":{},"output_type":"execute_result"}],"execution_count":15},{"id":"dcd14d6d-a072-4306-92d5-aae277318c54","cell_type":"markdown","source":"#### 1 middle edge","metadata":{}},{"id":"67649cc2-a6c6-4724-9d66-8df2bc758b85","cell_type":"code","source":"neatnet.remove_interstitial_nodes(\n geopandas.GeoDataFrame(geometry=[loop1, loop2, mid1])\n)","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:48.534828Z","iopub.status.busy":"2025-05-31T19:55:48.534106Z","iopub.status.idle":"2025-05-31T19:55:48.558881Z","shell.execute_reply":"2025-05-31T19:55:48.558560Z","shell.execute_reply.started":"2025-05-31T19:55:48.534767Z"},"trusted":true},"outputs":[{"data":{"text/html":"<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>geometry</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>LINESTRING (2 2, 1 1, 1 3, 2 2)</td>\n </tr>\n <tr>\n <th>1</th>\n <td>LINESTRING (6 2, 7 1, 7 3, 6 2)</td>\n </tr>\n <tr>\n <th>2</th>\n <td>LINESTRING (2 2, 3 3, 5 3, 6 2)</td>\n </tr>\n </tbody>\n</table>\n</div>","text/plain":" geometry\n0 LINESTRING (2 2, 1 1, 1 3, 2 2)\n1 LINESTRING (6 2, 7 1, 7 3, 6 2)\n2 LINESTRING (2 2, 3 3, 5 3, 6 2)"},"execution_count":16,"metadata":{},"output_type":"execute_result"}],"execution_count":16},{"id":"a109ae63-04d4-4a2c-a8c9-e7742f356fe9","cell_type":"markdown","source":"#### 3 middle edges","metadata":{}},{"id":"3324d8ab-ae7e-4f70-9dee-c2f18863e07e","cell_type":"code","source":"mid3 = LineString((p06, p03))\n\nneatnet.remove_interstitial_nodes(\n geopandas.GeoDataFrame(geometry=[loop1, loop2, mid1, mid2, mid3])\n)","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:49.661173Z","iopub.status.busy":"2025-05-31T19:55:49.660918Z","iopub.status.idle":"2025-05-31T19:55:49.681498Z","shell.execute_reply":"2025-05-31T19:55:49.680992Z","shell.execute_reply.started":"2025-05-31T19:55:49.661156Z"},"trusted":true},"outputs":[{"data":{"text/html":"<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>geometry</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>LINESTRING (2 2, 1 1, 1 3, 2 2)</td>\n </tr>\n <tr>\n <th>1</th>\n <td>LINESTRING (6 2, 7 1, 7 3, 6 2)</td>\n </tr>\n <tr>\n <th>2</th>\n <td>LINESTRING (2 2, 3 3, 5 3, 6 2)</td>\n </tr>\n <tr>\n <th>3</th>\n <td>LINESTRING (6 2, 5 1, 3 1, 2 2)</td>\n </tr>\n <tr>\n <th>4</th>\n <td>LINESTRING (6 2, 2 2)</td>\n </tr>\n </tbody>\n</table>\n</div>","text/plain":" geometry\n0 LINESTRING (2 2, 1 1, 1 3, 2 2)\n1 LINESTRING (6 2, 7 1, 7 3, 6 2)\n2 LINESTRING (2 2, 3 3, 5 3, 6 2)\n3 LINESTRING (6 2, 5 1, 3 1, 2 2)\n4 LINESTRING (6 2, 2 2)"},"execution_count":17,"metadata":{},"output_type":"execute_result"}],"execution_count":17},{"id":"98c5ff05-3676-48af-b680-e94bc5b85ac9","cell_type":"markdown","source":"## Break down `remove_interstitial_nodes()` & `get_components()`","metadata":{}},{"id":"ac5fb9fc-0dbc-4334-91ba-717870d0c92c","cell_type":"code","source":"synthetic_edges = geopandas.GeoDataFrame(geometry=[loop1, loop2, mid1, mid2])\nsynthetic_edges.plot(cmap=\"Paired\", lw=5)","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:50.766763Z","iopub.status.busy":"2025-05-31T19:55:50.766081Z","iopub.status.idle":"2025-05-31T19:55:50.824541Z","shell.execute_reply":"2025-05-31T19:55:50.824299Z","shell.execute_reply.started":"2025-05-31T19:55:50.766709Z"},"trusted":true},"outputs":[{"data":{"text/plain":"<Axes: >"},"execution_count":18,"metadata":{},"output_type":"execute_result"},{"data":{"image/png":"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","text/plain":"<Figure size 640x480 with 1 Axes>"},"metadata":{},"output_type":"display_data"}],"execution_count":18},{"id":"ee548873-71fe-482f-b5de-527a4244a5ac","cell_type":"markdown","source":"### Internal processing prior to `get_components()` [call](https://github.com/uscuni/neatnet/blob/84a1dcac84b50d88be1eed294d3e00546a6c5f73/neatnet/nodes.py#L385)\n\n* [here](https://github.com/uscuni/neatnet/blob/84a1dcac84b50d88be1eed294d3e00546a6c5f73/neatnet/nodes.py#L383)","metadata":{}},{"id":"241349c8-c053-4ded-acd6-e3a2c98bfddf","cell_type":"code","source":"synthetic_edges = synthetic_edges.explode(ignore_index=True)\nsynthetic_edges","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:51.863672Z","iopub.status.busy":"2025-05-31T19:55:51.863368Z","iopub.status.idle":"2025-05-31T19:55:51.872536Z","shell.execute_reply":"2025-05-31T19:55:51.871999Z","shell.execute_reply.started":"2025-05-31T19:55:51.863653Z"},"trusted":true},"outputs":[{"data":{"text/html":"<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>geometry</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>LINESTRING (1 1, 1 3, 2 2, 1 1)</td>\n </tr>\n <tr>\n <th>1</th>\n <td>LINESTRING (7 1, 7 3, 6 2, 7 1)</td>\n </tr>\n <tr>\n <th>2</th>\n <td>LINESTRING (2 2, 3 3, 5 3, 6 2)</td>\n </tr>\n <tr>\n <th>3</th>\n <td>LINESTRING (6 2, 5 1, 3 1, 2 2)</td>\n </tr>\n </tbody>\n</table>\n</div>","text/plain":" geometry\n0 LINESTRING (1 1, 1 3, 2 2, 1 1)\n1 LINESTRING (7 1, 7 3, 6 2, 7 1)\n2 LINESTRING (2 2, 3 3, 5 3, 6 2)\n3 LINESTRING (6 2, 5 1, 3 1, 2 2)"},"execution_count":19,"metadata":{},"output_type":"execute_result"}],"execution_count":19},{"id":"97fa95b3-e1c4-4ad0-a603-cba37ed554d9","cell_type":"code","source":"synthetic_edges_get_components_input = synthetic_edges.geometry\nsynthetic_edges_get_components_input","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:52.470892Z","iopub.status.busy":"2025-05-31T19:55:52.470222Z","iopub.status.idle":"2025-05-31T19:55:52.480507Z","shell.execute_reply":"2025-05-31T19:55:52.479827Z","shell.execute_reply.started":"2025-05-31T19:55:52.470835Z"},"trusted":true},"outputs":[{"data":{"text/plain":"0 LINESTRING (1 1, 1 3, 2 2, 1 1)\n1 LINESTRING (7 1, 7 3, 6 2, 7 1)\n2 LINESTRING (2 2, 3 3, 5 3, 6 2)\n3 LINESTRING (6 2, 5 1, 3 1, 2 2)\nName: geometry, dtype: geometry"},"execution_count":20,"metadata":{},"output_type":"execute_result"}],"execution_count":20},{"id":"55948839-7483-4996-b531-1dead6d24fcd","cell_type":"markdown","source":"### Inside `get_components()`\n\n* [here](https://github.com/uscuni/neatnet/blob/84a1dcac84b50d88be1eed294d3e00546a6c5f73/neatnet/nodes.py#L134-L192)","metadata":{}},{"id":"33158bd8-e81b-4fd0-92d6-b9eade196449","cell_type":"code","source":"edgelines = edgelines = numpy.array(synthetic_edges_get_components_input)\nedgelines","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:53.734359Z","iopub.status.busy":"2025-05-31T19:55:53.733992Z","iopub.status.idle":"2025-05-31T19:55:53.738791Z","shell.execute_reply":"2025-05-31T19:55:53.738206Z","shell.execute_reply.started":"2025-05-31T19:55:53.734338Z"},"trusted":true},"outputs":[{"data":{"text/plain":"array([<LINESTRING (1 1, 1 3, 2 2, 1 1)>,\n <LINESTRING (7 1, 7 3, 6 2, 7 1)>,\n <LINESTRING (2 2, 3 3, 5 3, 6 2)>,\n <LINESTRING (6 2, 5 1, 3 1, 2 2)>], dtype=object)"},"execution_count":21,"metadata":{},"output_type":"execute_result"}],"execution_count":21},{"id":"bd9ec238-5f15-4cdc-9e41-c05aa5bb7fa9","cell_type":"code","source":"start_points = shapely.get_point(edgelines, 0)\nstart_points","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:54.396040Z","iopub.status.busy":"2025-05-31T19:55:54.395338Z","iopub.status.idle":"2025-05-31T19:55:54.403541Z","shell.execute_reply":"2025-05-31T19:55:54.402512Z","shell.execute_reply.started":"2025-05-31T19:55:54.395986Z"},"trusted":true},"outputs":[{"data":{"text/plain":"array([<POINT (1 1)>, <POINT (7 1)>, <POINT (2 2)>, <POINT (6 2)>],\n dtype=object)"},"execution_count":22,"metadata":{},"output_type":"execute_result"}],"execution_count":22},{"id":"a3efe6bb-5e8a-42ff-b7ab-de91f8b5bcdf","cell_type":"code","source":"end_points = shapely.get_point(edgelines, -1)\nend_points","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:54.732920Z","iopub.status.busy":"2025-05-31T19:55:54.732237Z","iopub.status.idle":"2025-05-31T19:55:54.740396Z","shell.execute_reply":"2025-05-31T19:55:54.739627Z","shell.execute_reply.started":"2025-05-31T19:55:54.732869Z"},"trusted":true},"outputs":[{"data":{"text/plain":"array([<POINT (1 1)>, <POINT (7 1)>, <POINT (6 2)>, <POINT (2 2)>],\n dtype=object)"},"execution_count":23,"metadata":{},"output_type":"execute_result"}],"execution_count":23},{"id":"2c61de34-536e-478e-8feb-125e7ab5a185","cell_type":"code","source":"points = shapely.points(\n numpy.unique(\n shapely.get_coordinates(numpy.concatenate([start_points, end_points])), axis=0\n )\n)\npoints","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:55.170457Z","iopub.status.busy":"2025-05-31T19:55:55.169771Z","iopub.status.idle":"2025-05-31T19:55:55.178664Z","shell.execute_reply":"2025-05-31T19:55:55.178044Z","shell.execute_reply.started":"2025-05-31T19:55:55.170405Z"},"trusted":true},"outputs":[{"data":{"text/plain":"array([<POINT (1 1)>, <POINT (2 2)>, <POINT (6 2)>, <POINT (7 1)>],\n dtype=object)"},"execution_count":24,"metadata":{},"output_type":"execute_result"}],"execution_count":24},{"id":"71de7b3f-c100-4d1b-bf06-848b594db508","cell_type":"code","source":"# query LineString geometry to identify points intersecting 2 geometries\ninp, res = shapely.STRtree(shapely.boundary(edgelines)).query(\n points, predicate=\"intersects\"\n)","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:55.844578Z","iopub.status.busy":"2025-05-31T19:55:55.844213Z","iopub.status.idle":"2025-05-31T19:55:55.848044Z","shell.execute_reply":"2025-05-31T19:55:55.847479Z","shell.execute_reply.started":"2025-05-31T19:55:55.844557Z"},"trusted":true},"outputs":[],"execution_count":25},{"id":"82f3c94b-f34b-4f6e-b8e6-2ccf3958f3fd","cell_type":"code","source":"inp","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:56.334422Z","iopub.status.busy":"2025-05-31T19:55:56.333741Z","iopub.status.idle":"2025-05-31T19:55:56.341425Z","shell.execute_reply":"2025-05-31T19:55:56.340650Z","shell.execute_reply.started":"2025-05-31T19:55:56.334371Z"},"trusted":true},"outputs":[{"data":{"text/plain":"array([1, 1, 2, 2])"},"execution_count":26,"metadata":{},"output_type":"execute_result"}],"execution_count":26},{"id":"1b339508-78ff-415d-b259-2ca35721c679","cell_type":"code","source":"res","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:56.902216Z","iopub.status.busy":"2025-05-31T19:55:56.901545Z","iopub.status.idle":"2025-05-31T19:55:56.909459Z","shell.execute_reply":"2025-05-31T19:55:56.908691Z","shell.execute_reply.started":"2025-05-31T19:55:56.902161Z"},"trusted":true},"outputs":[{"data":{"text/plain":"array([2, 3, 2, 3])"},"execution_count":27,"metadata":{},"output_type":"execute_result"}],"execution_count":27},{"id":"ac43edcc-92e5-4c9e-a6b0-5681c1100514","cell_type":"code","source":"unique, counts = numpy.unique(inp, return_counts=True)","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:57.613598Z","iopub.status.busy":"2025-05-31T19:55:57.613236Z","iopub.status.idle":"2025-05-31T19:55:57.617217Z","shell.execute_reply":"2025-05-31T19:55:57.616458Z","shell.execute_reply.started":"2025-05-31T19:55:57.613578Z"},"trusted":true},"outputs":[],"execution_count":28},{"id":"015e7f26-1f2d-4507-bfad-e8905349cee9","cell_type":"code","source":"unique","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:57.912908Z","iopub.status.busy":"2025-05-31T19:55:57.912658Z","iopub.status.idle":"2025-05-31T19:55:57.916270Z","shell.execute_reply":"2025-05-31T19:55:57.915853Z","shell.execute_reply.started":"2025-05-31T19:55:57.912892Z"},"trusted":true},"outputs":[{"data":{"text/plain":"array([1, 2])"},"execution_count":29,"metadata":{},"output_type":"execute_result"}],"execution_count":29},{"id":"92926267-60f3-4ea6-ac58-06035d09c3dd","cell_type":"code","source":"counts","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:58.433422Z","iopub.status.busy":"2025-05-31T19:55:58.432765Z","iopub.status.idle":"2025-05-31T19:55:58.440217Z","shell.execute_reply":"2025-05-31T19:55:58.439345Z","shell.execute_reply.started":"2025-05-31T19:55:58.433371Z"},"trusted":true},"outputs":[{"data":{"text/plain":"array([2, 2])"},"execution_count":30,"metadata":{},"output_type":"execute_result"}],"execution_count":30},{"id":"fff9c233-1f75-481a-9cdd-afb80491a9e3","cell_type":"code","source":"mask = numpy.isin(inp, unique[counts == 2])\nmask","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:59.074365Z","iopub.status.busy":"2025-05-31T19:55:59.073691Z","iopub.status.idle":"2025-05-31T19:55:59.082306Z","shell.execute_reply":"2025-05-31T19:55:59.081589Z","shell.execute_reply.started":"2025-05-31T19:55:59.074312Z"},"trusted":true},"outputs":[{"data":{"text/plain":"array([ True, True, True, True])"},"execution_count":31,"metadata":{},"output_type":"execute_result"}],"execution_count":31},{"id":"b7931ab7-7db3-40b9-ae19-8899dd0dbd6a","cell_type":"code","source":"merge_res = res[mask]\nmerge_res","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:55:59.604341Z","iopub.status.busy":"2025-05-31T19:55:59.603960Z","iopub.status.idle":"2025-05-31T19:55:59.608582Z","shell.execute_reply":"2025-05-31T19:55:59.608039Z","shell.execute_reply.started":"2025-05-31T19:55:59.604321Z"},"trusted":true},"outputs":[{"data":{"text/plain":"array([2, 3, 2, 3])"},"execution_count":32,"metadata":{},"output_type":"execute_result"}],"execution_count":32},{"id":"3273ad2d-c751-42f4-9b5d-c3de87113551","cell_type":"code","source":"merge_inp = inp[mask]\nmerge_inp","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:56:00.304375Z","iopub.status.busy":"2025-05-31T19:56:00.303798Z","iopub.status.idle":"2025-05-31T19:56:00.310678Z","shell.execute_reply":"2025-05-31T19:56:00.310080Z","shell.execute_reply.started":"2025-05-31T19:56:00.304327Z"},"trusted":true},"outputs":[{"data":{"text/plain":"array([1, 1, 2, 2])"},"execution_count":33,"metadata":{},"output_type":"execute_result"}],"execution_count":33},{"id":"412c4c01-cbe9-454d-a101-c20a698951ad","cell_type":"code","source":"closed = numpy.arange(len(edgelines))[shapely.is_closed(edgelines)]\nclosed","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:56:00.791745Z","iopub.status.busy":"2025-05-31T19:56:00.791146Z","iopub.status.idle":"2025-05-31T19:56:00.799993Z","shell.execute_reply":"2025-05-31T19:56:00.799255Z","shell.execute_reply.started":"2025-05-31T19:56:00.791704Z"},"trusted":true},"outputs":[{"data":{"text/plain":"array([0, 1])"},"execution_count":34,"metadata":{},"output_type":"execute_result"}],"execution_count":34},{"id":"d1588b9f-e115-4ce5-ade7-42c83ecc6057","cell_type":"code","source":"mask = numpy.isin(merge_res, closed) | numpy.isin(merge_inp, closed)\nmask","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:56:01.220608Z","iopub.status.busy":"2025-05-31T19:56:01.220228Z","iopub.status.idle":"2025-05-31T19:56:01.225139Z","shell.execute_reply":"2025-05-31T19:56:01.224610Z","shell.execute_reply.started":"2025-05-31T19:56:01.220586Z"},"trusted":true},"outputs":[{"data":{"text/plain":"array([ True, True, False, False])"},"execution_count":35,"metadata":{},"output_type":"execute_result"}],"execution_count":35},{"id":"abad3d32-fbb2-47ea-8416-fef37e433326","cell_type":"code","source":"merge_res = merge_res[~mask]\nmerge_res","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:56:01.688865Z","iopub.status.busy":"2025-05-31T19:56:01.688410Z","iopub.status.idle":"2025-05-31T19:56:01.693378Z","shell.execute_reply":"2025-05-31T19:56:01.692805Z","shell.execute_reply.started":"2025-05-31T19:56:01.688844Z"},"trusted":true},"outputs":[{"data":{"text/plain":"array([2, 3])"},"execution_count":36,"metadata":{},"output_type":"execute_result"}],"execution_count":36},{"id":"4f1a0217-f0a4-434e-97dc-698f14dd3dd7","cell_type":"code","source":"merge_inp = merge_inp[~mask]\nmerge_inp","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:56:02.200016Z","iopub.status.busy":"2025-05-31T19:56:02.199350Z","iopub.status.idle":"2025-05-31T19:56:02.206978Z","shell.execute_reply":"2025-05-31T19:56:02.205890Z","shell.execute_reply.started":"2025-05-31T19:56:02.199973Z"},"trusted":true},"outputs":[{"data":{"text/plain":"array([2, 2])"},"execution_count":37,"metadata":{},"output_type":"execute_result"}],"execution_count":37},{"id":"29257f2e-5999-4218-a429-203e5694c27c","cell_type":"code","source":"#g = networkx.Graph(list(zip((merge_inp * -1) - 1, merge_res, strict=True)))\n#g","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:56:02.834885Z","iopub.status.busy":"2025-05-31T19:56:02.834366Z","iopub.status.idle":"2025-05-31T19:56:02.838970Z","shell.execute_reply":"2025-05-31T19:56:02.837887Z","shell.execute_reply.started":"2025-05-31T19:56:02.834845Z"},"trusted":true},"outputs":[],"execution_count":38},{"id":"b8b00225-5f5e-494c-8c55-cb9c43a33746","cell_type":"code","source":"nodes_component_list = list(zip((merge_inp * -1) - 1, merge_res, strict=True))\nnodes_component_list","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:56:03.482665Z","iopub.status.busy":"2025-05-31T19:56:03.482360Z","iopub.status.idle":"2025-05-31T19:56:03.486322Z","shell.execute_reply":"2025-05-31T19:56:03.485873Z","shell.execute_reply.started":"2025-05-31T19:56:03.482646Z"},"trusted":true},"outputs":[{"data":{"text/plain":"[(np.int64(-3), np.int64(2)), (np.int64(-3), np.int64(3))]"},"execution_count":39,"metadata":{},"output_type":"execute_result"}],"execution_count":39},{"id":"96dacc3f-2793-404f-b9e2-46a8702195a9","cell_type":"code","source":"g = networkx.Graph(nodes_component_list)\ng","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:56:03.846044Z","iopub.status.busy":"2025-05-31T19:56:03.845713Z","iopub.status.idle":"2025-05-31T19:56:03.850301Z","shell.execute_reply":"2025-05-31T19:56:03.849818Z","shell.execute_reply.started":"2025-05-31T19:56:03.846022Z"},"trusted":true},"outputs":[{"data":{"text/plain":"<networkx.classes.graph.Graph at 0x1670ee7a0>"},"execution_count":40,"metadata":{},"output_type":"execute_result"}],"execution_count":40},{"id":"79bc3c25-5cbe-4780-bf81-28dc591d2aa1","cell_type":"code","source":"components = {\n i: {v for v in k if v > -1} for i, k in enumerate(networkx.connected_components(g))\n}\ncomponents","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:56:04.155630Z","iopub.status.busy":"2025-05-31T19:56:04.155329Z","iopub.status.idle":"2025-05-31T19:56:04.159542Z","shell.execute_reply":"2025-05-31T19:56:04.159075Z","shell.execute_reply.started":"2025-05-31T19:56:04.155611Z"},"trusted":true},"outputs":[{"data":{"text/plain":"{0: {np.int64(2), np.int64(3)}}"},"execution_count":41,"metadata":{},"output_type":"execute_result"}],"execution_count":41},{"id":"17d6a824-cb58-4b0e-a2f4-36c9259b368d","cell_type":"code","source":"component_labels = {value: key for key in components for value in components[key]}\ncomponent_labels","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:56:04.505685Z","iopub.status.busy":"2025-05-31T19:56:04.505155Z","iopub.status.idle":"2025-05-31T19:56:04.512168Z","shell.execute_reply":"2025-05-31T19:56:04.511365Z","shell.execute_reply.started":"2025-05-31T19:56:04.505644Z"},"trusted":true},"outputs":[{"data":{"text/plain":"{np.int64(2): 0, np.int64(3): 0}"},"execution_count":42,"metadata":{},"output_type":"execute_result"}],"execution_count":42},{"id":"99d34ae9-c2fc-44e8-bf59-0e46f9b321dd","cell_type":"code","source":"labels = pandas.Series(component_labels, index=range(len(edgelines)))\nlabels","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:56:05.015851Z","iopub.status.busy":"2025-05-31T19:56:05.015271Z","iopub.status.idle":"2025-05-31T19:56:05.024358Z","shell.execute_reply":"2025-05-31T19:56:05.023534Z","shell.execute_reply.started":"2025-05-31T19:56:05.015803Z"},"trusted":true},"outputs":[{"data":{"text/plain":"0 NaN\n1 NaN\n2 0.0\n3 0.0\ndtype: float64"},"execution_count":43,"metadata":{},"output_type":"execute_result"}],"execution_count":43},{"id":"96d4258c-31bf-4a79-9016-21c3d23e7c7b","cell_type":"code","source":"max_label = len(edgelines) - 1 if pandas.isna(labels.max()) else int(labels.max())\nmax_label","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:56:05.565615Z","iopub.status.busy":"2025-05-31T19:56:05.565082Z","iopub.status.idle":"2025-05-31T19:56:05.572617Z","shell.execute_reply":"2025-05-31T19:56:05.572022Z","shell.execute_reply.started":"2025-05-31T19:56:05.565573Z"},"trusted":true},"outputs":[{"data":{"text/plain":"0"},"execution_count":44,"metadata":{},"output_type":"execute_result"}],"execution_count":44},{"id":"baaf08db-83b6-4d20-ae64-78c0c7154eb9","cell_type":"code","source":"filling = pandas.Series(range(max_label + 1, max_label + len(edgelines) + 1))\nfilling","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:56:06.183212Z","iopub.status.busy":"2025-05-31T19:56:06.182689Z","iopub.status.idle":"2025-05-31T19:56:06.189365Z","shell.execute_reply":"2025-05-31T19:56:06.188550Z","shell.execute_reply.started":"2025-05-31T19:56:06.183166Z"},"trusted":true},"outputs":[{"data":{"text/plain":"0 1\n1 2\n2 3\n3 4\ndtype: int64"},"execution_count":45,"metadata":{},"output_type":"execute_result"}],"execution_count":45},{"id":"8fd37a1f-132c-4eb8-8453-35faa8492aa1","cell_type":"code","source":"labels = labels.fillna(filling)\nlabels","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:56:06.693921Z","iopub.status.busy":"2025-05-31T19:56:06.693653Z","iopub.status.idle":"2025-05-31T19:56:06.698153Z","shell.execute_reply":"2025-05-31T19:56:06.697722Z","shell.execute_reply.started":"2025-05-31T19:56:06.693902Z"},"trusted":true},"outputs":[{"data":{"text/plain":"0 1.0\n1 2.0\n2 0.0\n3 0.0\ndtype: float64"},"execution_count":46,"metadata":{},"output_type":"execute_result"}],"execution_count":46},{"id":"7222c8ea-1050-4239-aabc-6adf5f26b2ba","cell_type":"code","source":"labels = labels.values\nlabels","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:56:07.404687Z","iopub.status.busy":"2025-05-31T19:56:07.404086Z","iopub.status.idle":"2025-05-31T19:56:07.410709Z","shell.execute_reply":"2025-05-31T19:56:07.410283Z","shell.execute_reply.started":"2025-05-31T19:56:07.404638Z"},"trusted":true},"outputs":[{"data":{"text/plain":"array([1., 2., 0., 0.])"},"execution_count":47,"metadata":{},"output_type":"execute_result"}],"execution_count":47},{"id":"a94d8ecb-ef54-4e9e-b83a-2572b1b2006c","cell_type":"markdown","source":"### Following `get_components()`\n\n* [here](https://github.com/uscuni/neatnet/blob/84a1dcac84b50d88be1eed294d3e00546a6c5f73/neatnet/nodes.py#L387-L404)","metadata":{}},{"id":"5b1c603e-5bfe-43c1-a326-e5d8406824dd","cell_type":"code","source":"data = synthetic_edges.drop(labels=synthetic_edges.geometry.name, axis=1)\ndata","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:56:08.550503Z","iopub.status.busy":"2025-05-31T19:56:08.550084Z","iopub.status.idle":"2025-05-31T19:56:08.557426Z","shell.execute_reply":"2025-05-31T19:56:08.557011Z","shell.execute_reply.started":"2025-05-31T19:56:08.550478Z"},"trusted":true},"outputs":[{"data":{"text/html":"<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n </tr>\n <tr>\n <th>1</th>\n </tr>\n <tr>\n <th>2</th>\n </tr>\n <tr>\n <th>3</th>\n </tr>\n </tbody>\n</table>\n</div>","text/plain":"Empty DataFrame\nColumns: []\nIndex: [0, 1, 2, 3]"},"execution_count":48,"metadata":{},"output_type":"execute_result"}],"execution_count":48},{"id":"af278fd3-42b5-4352-9232-dda7fd08ac32","cell_type":"code","source":"aggfunc = \"first\"\nkwargs = {}\n\naggregated_data = data.groupby(by=labels).agg(aggfunc, **kwargs)\naggregated_data","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:56:09.225710Z","iopub.status.busy":"2025-05-31T19:56:09.225339Z","iopub.status.idle":"2025-05-31T19:56:09.232410Z","shell.execute_reply":"2025-05-31T19:56:09.231947Z","shell.execute_reply.started":"2025-05-31T19:56:09.225689Z"},"trusted":true},"outputs":[{"data":{"text/html":"<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0.0</th>\n </tr>\n <tr>\n <th>1.0</th>\n </tr>\n <tr>\n <th>2.0</th>\n </tr>\n </tbody>\n</table>\n</div>","text/plain":"Empty DataFrame\nColumns: []\nIndex: [0.0, 1.0, 2.0]"},"execution_count":49,"metadata":{},"output_type":"execute_result"}],"execution_count":49},{"id":"ee115588-1157-46c1-8a37-e3558c883753","cell_type":"code","source":"aggregated_data.columns = aggregated_data.columns.to_flat_index()\naggregated_data","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:56:09.825820Z","iopub.status.busy":"2025-05-31T19:56:09.825337Z","iopub.status.idle":"2025-05-31T19:56:09.832720Z","shell.execute_reply":"2025-05-31T19:56:09.832386Z","shell.execute_reply.started":"2025-05-31T19:56:09.825782Z"},"trusted":true},"outputs":[{"data":{"text/html":"<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0.0</th>\n </tr>\n <tr>\n <th>1.0</th>\n </tr>\n <tr>\n <th>2.0</th>\n </tr>\n </tbody>\n</table>\n</div>","text/plain":"Empty DataFrame\nColumns: []\nIndex: [0.0, 1.0, 2.0]"},"execution_count":50,"metadata":{},"output_type":"execute_result"}],"execution_count":50},{"id":"a74b7c78-f818-4af7-94e1-d520901e5659","cell_type":"markdown","source":"### Merges our 2 lines onto 1 loop due to labeling from `get_components()`\n\n#### internal merging func\n\n* [here](https://github.com/uscuni/neatnet/blob/84a1dcac84b50d88be1eed294d3e00546a6c5f73/neatnet/nodes.py#L373-L375)","metadata":{}},{"id":"128bb2f0-8727-42a2-bc90-cc5e0a14ce8a","cell_type":"code","source":"def merge_geometries(block):\n \"\"\"Helper in processing the spatial component.\"\"\"\n return shapely.line_merge(shapely.GeometryCollection(block.values))","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:56:11.137168Z","iopub.status.busy":"2025-05-31T19:56:11.136722Z","iopub.status.idle":"2025-05-31T19:56:11.140568Z","shell.execute_reply":"2025-05-31T19:56:11.140012Z","shell.execute_reply.started":"2025-05-31T19:56:11.137139Z"},"trusted":true},"outputs":[],"execution_count":51},{"id":"f00bb454-a7ce-4d38-b9ae-cd6edf54154c","cell_type":"code","source":"g = (\n synthetic_edges\n .groupby(group_keys=False, by=labels)\n [synthetic_edges.geometry.name]\n .agg(merge_geometries)\n)\naggregated_geometry = geopandas.GeoDataFrame(\n g, geometry=synthetic_edges.geometry.name, crs=synthetic_edges.crs\n)\naggregated_geometry","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:56:11.681722Z","iopub.status.busy":"2025-05-31T19:56:11.681038Z","iopub.status.idle":"2025-05-31T19:56:11.697084Z","shell.execute_reply":"2025-05-31T19:56:11.696565Z","shell.execute_reply.started":"2025-05-31T19:56:11.681667Z"},"trusted":true},"outputs":[{"data":{"text/html":"<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>geometry</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0.0</th>\n <td>LINESTRING (2 2, 3 3, 5 3, 6 2, 5 1, 3 1, 2 2)</td>\n </tr>\n <tr>\n <th>1.0</th>\n <td>LINESTRING (1 1, 1 3, 2 2, 1 1)</td>\n </tr>\n <tr>\n <th>2.0</th>\n <td>LINESTRING (7 1, 7 3, 6 2, 7 1)</td>\n </tr>\n </tbody>\n</table>\n</div>","text/plain":" geometry\n0.0 LINESTRING (2 2, 3 3, 5 3, 6 2, 5 1, 3 1, 2 2)\n1.0 LINESTRING (1 1, 1 3, 2 2, 1 1)\n2.0 LINESTRING (7 1, 7 3, 6 2, 7 1)"},"execution_count":52,"metadata":{},"output_type":"execute_result"}],"execution_count":52},{"id":"8968d489-4c15-4779-bafe-81aa3f9ea6c8","cell_type":"code","source":"aggregated_geometry.plot(cmap=\"Paired\")","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:56:12.464471Z","iopub.status.busy":"2025-05-31T19:56:12.464095Z","iopub.status.idle":"2025-05-31T19:56:12.520026Z","shell.execute_reply":"2025-05-31T19:56:12.519759Z","shell.execute_reply.started":"2025-05-31T19:56:12.464449Z"},"trusted":true},"outputs":[{"data":{"text/plain":"<Axes: >"},"execution_count":53,"metadata":{},"output_type":"execute_result"},{"data":{"image/png":"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","text/plain":"<Figure size 640x480 with 1 Axes>"},"metadata":{},"output_type":"display_data"}],"execution_count":53},{"id":"55e5ab89-acb6-4c99-bf94-29d05f78c932","cell_type":"code","source":"aggregated = aggregated_geometry.join(aggregated_data)\naggregated","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:56:13.290860Z","iopub.status.busy":"2025-05-31T19:56:13.290343Z","iopub.status.idle":"2025-05-31T19:56:13.303100Z","shell.execute_reply":"2025-05-31T19:56:13.302431Z","shell.execute_reply.started":"2025-05-31T19:56:13.290818Z"},"trusted":true},"outputs":[{"data":{"text/html":"<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>geometry</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0.0</th>\n <td>LINESTRING (2 2, 3 3, 5 3, 6 2, 5 1, 3 1, 2 2)</td>\n </tr>\n <tr>\n <th>1.0</th>\n <td>LINESTRING (1 1, 1 3, 2 2, 1 1)</td>\n </tr>\n <tr>\n <th>2.0</th>\n <td>LINESTRING (7 1, 7 3, 6 2, 7 1)</td>\n </tr>\n </tbody>\n</table>\n</div>","text/plain":" geometry\n0.0 LINESTRING (2 2, 3 3, 5 3, 6 2, 5 1, 3 1, 2 2)\n1.0 LINESTRING (1 1, 1 3, 2 2, 1 1)\n2.0 LINESTRING (7 1, 7 3, 6 2, 7 1)"},"execution_count":54,"metadata":{},"output_type":"execute_result"}],"execution_count":54},{"id":"94f907e1-ef4c-4fe2-83dd-5e620f88b44f","cell_type":"code","source":"# Derive nodes\nnodes = neatnet.nodes._nodes_from_edges(aggregated.geometry)\nnodes","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:56:14.250716Z","iopub.status.busy":"2025-05-31T19:56:14.250153Z","iopub.status.idle":"2025-05-31T19:56:14.258519Z","shell.execute_reply":"2025-05-31T19:56:14.257894Z","shell.execute_reply.started":"2025-05-31T19:56:14.250666Z"},"trusted":true},"outputs":[{"data":{"text/plain":"array([<POINT (1 1)>, <POINT (2 2)>, <POINT (7 1)>], dtype=object)"},"execution_count":55,"metadata":{},"output_type":"execute_result"}],"execution_count":55},{"id":"e36178a1-ca0a-4a11-9780-13b67bf5561a","cell_type":"code","source":"# Bifurcate edges into loops and non-loops\nloops, not_loops = neatnet.nodes._loops_and_non_loops(aggregated)","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:56:15.214430Z","iopub.status.busy":"2025-05-31T19:56:15.213865Z","iopub.status.idle":"2025-05-31T19:56:15.220963Z","shell.execute_reply":"2025-05-31T19:56:15.220262Z","shell.execute_reply.started":"2025-05-31T19:56:15.214382Z"},"trusted":true},"outputs":[],"execution_count":56},{"id":"da32bb9b-1a3f-4826-8813-36469d72c6dc","cell_type":"code","source":"loops","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:56:15.601549Z","iopub.status.busy":"2025-05-31T19:56:15.600866Z","iopub.status.idle":"2025-05-31T19:56:15.612453Z","shell.execute_reply":"2025-05-31T19:56:15.611959Z","shell.execute_reply.started":"2025-05-31T19:56:15.601496Z"},"trusted":true},"outputs":[{"data":{"text/html":"<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>geometry</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0.0</th>\n <td>LINESTRING (2 2, 3 3, 5 3, 6 2, 5 1, 3 1, 2 2)</td>\n </tr>\n <tr>\n <th>1.0</th>\n <td>LINESTRING (1 1, 1 3, 2 2, 1 1)</td>\n </tr>\n <tr>\n <th>2.0</th>\n <td>LINESTRING (7 1, 7 3, 6 2, 7 1)</td>\n </tr>\n </tbody>\n</table>\n</div>","text/plain":" geometry\n0.0 LINESTRING (2 2, 3 3, 5 3, 6 2, 5 1, 3 1, 2 2)\n1.0 LINESTRING (1 1, 1 3, 2 2, 1 1)\n2.0 LINESTRING (7 1, 7 3, 6 2, 7 1)"},"execution_count":57,"metadata":{},"output_type":"execute_result"}],"execution_count":57},{"id":"8aeda79f-1a94-4482-9225-f4f530a7c95d","cell_type":"code","source":"not_loops","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:56:16.451668Z","iopub.status.busy":"2025-05-31T19:56:16.451292Z","iopub.status.idle":"2025-05-31T19:56:16.457909Z","shell.execute_reply":"2025-05-31T19:56:16.457069Z","shell.execute_reply.started":"2025-05-31T19:56:16.451645Z"},"trusted":true},"outputs":[{"data":{"text/html":"<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>geometry</th>\n </tr>\n </thead>\n <tbody>\n </tbody>\n</table>\n</div>","text/plain":"Empty GeoDataFrame\nColumns: [geometry]\nIndex: []"},"execution_count":58,"metadata":{},"output_type":"execute_result"}],"execution_count":58},{"id":"1063607b-d1e7-4a5d-a5d5-206f3e00a0bf","cell_type":"markdown","source":"### Replicate error due to:\n\n1. Erronoeus merge of 2 edges in 1 loop\n2. Then target loops only intersecting other loops","metadata":{}},{"id":"28c98926-750e-4f25-a58a-ed2fd87f65a9","cell_type":"code","source":"# Ensure:\n# - all loops have exactly 1 endpoint; and\n# - that endpoint shares a node with an intersecting line\nfixed_loops = []\nfixed_index = []\nnode_ix, loop_ix = loops.sindex.query(nodes, predicate=\"intersects\")\nfor ix in numpy.unique(loop_ix):\n loop_geom = loops.geometry.iloc[ix]\n target_nodes = nodes[node_ix[loop_ix == ix]]\n if len(target_nodes) == 2:\n new_sequence = neatnet.nodes._rotate_loop_coords(loop_geom, not_loops)\n fixed_loops.append(shapely.LineString(new_sequence))\n fixed_index.append(ix)","metadata":{"execution":{"iopub.execute_input":"2025-05-31T19:56:18.142766Z","iopub.status.busy":"2025-05-31T19:56:18.142190Z","iopub.status.idle":"2025-05-31T19:56:18.181742Z","shell.execute_reply":"2025-05-31T19:56:18.181299Z","shell.execute_reply.started":"2025-05-31T19:56:18.142722Z"},"trusted":true},"outputs":[{"ename":"ValueError","evalue":"operands could not be broadcast together with shapes (4,2) (0,2) ","output_type":"error","traceback":["\u001b[31m---------------------------------------------------------------------------\u001b[39m","\u001b[31mValueError\u001b[39m Traceback (most recent call last)","\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[59]\u001b[39m\u001b[32m, line 11\u001b[39m\n\u001b[32m 9\u001b[39m target_nodes = nodes[node_ix[loop_ix == ix]]\n\u001b[32m 10\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(target_nodes) == \u001b[32m2\u001b[39m:\n\u001b[32m---> \u001b[39m\u001b[32m11\u001b[39m new_sequence = \u001b[43mneatnet\u001b[49m\u001b[43m.\u001b[49m\u001b[43mnodes\u001b[49m\u001b[43m.\u001b[49m\u001b[43m_rotate_loop_coords\u001b[49m\u001b[43m(\u001b[49m\u001b[43mloop_geom\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mnot_loops\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 12\u001b[39m fixed_loops.append(shapely.LineString(new_sequence))\n\u001b[32m 13\u001b[39m fixed_index.append(ix)\n","\u001b[36mFile \u001b[39m\u001b[32m~/github_repos/uscuni/neatnet/neatnet/nodes.py:449\u001b[39m, in \u001b[36m_rotate_loop_coords\u001b[39m\u001b[34m(loop_geom, not_loops)\u001b[39m\n\u001b[32m 446\u001b[39m mode = mode.iloc[[\u001b[32m0\u001b[39m]]\n\u001b[32m 448\u001b[39m new_start = mode.get_coordinates().values\n\u001b[32m--> \u001b[39m\u001b[32m449\u001b[39m _coords_match = (\u001b[43mloop_coords\u001b[49m\u001b[43m \u001b[49m\u001b[43m==\u001b[49m\u001b[43m \u001b[49m\u001b[43mnew_start\u001b[49m).all(axis=\u001b[32m1\u001b[39m)\n\u001b[32m 450\u001b[39m new_start_idx = np.where(_coords_match)[\u001b[32m0\u001b[39m].squeeze()\n\u001b[32m 452\u001b[39m rolled_coords = np.roll(loop_coords[:-\u001b[32m1\u001b[39m], -new_start_idx, axis=\u001b[32m0\u001b[39m)\n","\u001b[31mValueError\u001b[39m: operands could not be broadcast together with shapes (4,2) (0,2) "]}],"execution_count":59}]} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment