-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #23 from tariqshihadah/dev
Prepare for 0.1.1 release
- Loading branch information
Showing
12 changed files
with
1,159 additions
and
34 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,221 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"id": "cecaac91-c136-4042-a519-004e792ba3e9", | ||
"metadata": {}, | ||
"source": [ | ||
"# Generating line geometries from a table of line-events with known Route IDs and mile markers\n", | ||
"\n", | ||
"Suppose we have a table of line events with Route ID and mile marker information about where each event happened, but with no associated geometries. \n", | ||
"Suppose further that we also have the linework of the reference routes. \n", | ||
"\n", | ||
"We can use `linref` to generate geometries for each of the rows of the line data. The example below shows the step-by-step process." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 8, | ||
"id": "7c4eb0d7-a00c-44fb-9b89-73652a1d6327", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# Import dependencies\n", | ||
"from shapely.geometry import LineString\n", | ||
"import pandas as pd\n", | ||
"import geopandas as gpd\n", | ||
"import linref as lr" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "0f552310-3fb3-481d-8901-61cd4e82ff89", | ||
"metadata": {}, | ||
"source": [ | ||
"First, let's create the sample DataFrames and GeoDataFrames we'll be using throughout this example." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 9, | ||
"id": "2067add6-53de-4d7f-aab9-846a50b44926", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# `line_df` is the DataFrame containing the lines with route ID and mile marker info but without any\n", | ||
"# actual geometries \n", | ||
"line_df = pd.DataFrame({\n", | ||
" 'line_id':[1,2,3,4],\n", | ||
" 'route_id':['A','A','B','B'],\n", | ||
" 'beg':[1,2,2,3],\n", | ||
" 'end':[2,3,3,4]\n", | ||
"})\n", | ||
"\n", | ||
"\n", | ||
"# `ref_gdf` is the GeoDataFrame that contains the reference linework of the roadway network\n", | ||
"ref_gdf = gpd.GeoDataFrame({\n", | ||
" 'route_id': ['A','B'],\n", | ||
" 'beg': [0,0],\n", | ||
" 'end': [5,5],\n", | ||
" 'geometry': [LineString(((0,0),(5,0))), LineString(((0,2),(5,2)))]\n", | ||
"})" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "4ec5b870-b919-40f2-a296-c876a763ed98", | ||
"metadata": {}, | ||
"source": [ | ||
"The first processing step is to create `EventCollection` objects for both sets:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 10, | ||
"id": "4151acae-13b6-41ce-9d00-029766c45276", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# For the reference object, notice how we specify the `beg` and `end` parameters because we are dealing with a link-based object.\n", | ||
"# The idea here is that the `beg` and `end` columns indicate which columns contain the start and end mile marker information for \n", | ||
"# each link. \n", | ||
"ref_ec = lr.EventsCollection(\n", | ||
" ref_gdf,\n", | ||
" keys=['route_id'],\n", | ||
" beg='beg',\n", | ||
" end='end',\n", | ||
" geom='geometry'\n", | ||
")\n", | ||
"\n", | ||
"# For the line object, we also need to specify the `beg` and `end` parameters. \n", | ||
"line_ec = lr.EventsCollection(\n", | ||
" line_df, \n", | ||
" keys=['route_id'],\n", | ||
" beg='beg',\n", | ||
" end='end'\n", | ||
")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "59c9f888-e73d-4a1c-9235-38d8e423c9b9", | ||
"metadata": {}, | ||
"source": [ | ||
"We then need to build the routes for the reference `EventsCollection` object.\n", | ||
"This step directs the `linref` library to perform some internal processing steps that are required for GIS-based operations." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 11, | ||
"id": "3cd299b7-e762-4d5d-a9f1-a095fb0e790b", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"ref_ec.build_routes()" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "16b25371-447b-4019-aaba-fee9d57ddf45", | ||
"metadata": {}, | ||
"source": [ | ||
"Then, we can create the new geometries by merging the `line_ec` with the `ref_ec` and applying the `cut()` method. \n", | ||
"This will generate a numpy array of `MultiLineString` geometries, which can easily be added to your DataFrame. " | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 12, | ||
"id": "b709333b-6f87-4df4-8dee-82661ec4b95e", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"2 MULTILINESTRING ((2 2, 3 2))\n", | ||
"3 MULTILINESTRING ((3 2, 4 2))\n", | ||
"0 MULTILINESTRING ((1 0, 2 0))\n", | ||
"1 MULTILINESTRING ((2 0, 3 0))\n", | ||
"Name: route, dtype: object\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"# Now we can merge the point and reference EventsCollections and cut new geometries. The `merge` method defines \n", | ||
"# a linearly referenced relationship between the target and merged collections which can be used to cut new geometries. \n", | ||
"# This relationship is captured and managed within an `EventsMerge` object, commonly referred to as `em`.\n", | ||
"em = line_ec.merge(ref_ec)\n", | ||
"\n", | ||
"# The `cut` method is one of the many aggregators available using the `EventsMerge` class.\n", | ||
"new_geoms = em.cut()\n", | ||
"print(new_geoms)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "5cc64d52-6ab5-4f22-835a-c0f3fd811c0a", | ||
"metadata": {}, | ||
"source": [ | ||
"Finally, if you want to want to create a full-fledged GeoDataFrame, you can just make a copy of your original input DataFrame and add the new array of lines as the geometry column." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 14, | ||
"id": "073e2a67-b1db-4eb4-9023-e962523ee911", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
" line_id route_id beg end \\\n", | ||
"0 1 A 1 2 \n", | ||
"1 2 A 2 3 \n", | ||
"2 3 B 2 3 \n", | ||
"3 4 B 3 4 \n", | ||
"\n", | ||
" geometry \n", | ||
"0 MULTILINESTRING ((1.00000 0.00000, 2.00000 0.0... \n", | ||
"1 MULTILINESTRING ((2.00000 0.00000, 3.00000 0.0... \n", | ||
"2 MULTILINESTRING ((2.00000 2.00000, 3.00000 2.0... \n", | ||
"3 MULTILINESTRING ((3.00000 2.00000, 4.00000 2.0... \n", | ||
" line_id route_id beg end\n", | ||
"0 1 A 1 2\n", | ||
"1 2 A 2 3\n", | ||
"2 3 B 2 3\n", | ||
"3 4 B 3 4\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"# Create a new GeoDataFrame with the interpolated geometries\n", | ||
"line_gdf = gpd.GeoDataFrame(line_df, geometry=new_geoms)\n", | ||
"print(line_gdf)" | ||
] | ||
} | ||
], | ||
"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.11.7" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 5 | ||
} |
Oops, something went wrong.