Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
A Python package to find the centerline and width of rivers based on the latitude and longitude of the right and left bank
Find the centerline and width of rivers based on the latitude and longitude positions from the right and left bank
River Outlined in Google Earth Pro | Generated Centerline for the Riverbank |
---|---|
[!NOTE] This is Beta quality software that is being actively developed, use at your own risk. This project is not supported or endorsed by either JPL or NASA. The code is provided “as is”, use at your own risk.
PyPi pip install at pypi.org/project/centerline-width/
pip install centerline-width
The core of centerline-width works with a .csv file of the left and right bank latitude/longitudes. So, if starting from Google Earth Pro, two .kml must first be translated to a single .csv file
import centerline_width
centerline_width.kml_to_csv(left_kml="left_bank.kml",
right_kml="right_bank.kml",
text_output_name="river_coordinates_output.csv")
Then once the .csv file is created, to run the centerline-width functions, generate a river object from the river_coordinates_output.csv
river_object = centerline_width.CenterlineWidth(csv_data="river_coordinates_output.csv")
To plot the centerline, run the plot_centerline()
function from river_object
created. By default, will display with Decimal Degrees
(latitude/longitude) coordinates
river_object.plot_centerline()
To plot the width of the river at intervals along the bank, run plot_centerline_width()
While apply_smoothing
, remove_intersections
, and display_true_centerline
are optional, they are recommended to generate a minimal width diagram
river_object.plot_centerline_width(apply_smoothing=True, remove_intersections=True, display_true_centerline=False)
It is possible to also display all the coordinates as a Relative Distance
, where all the coordinates are converted to a relative distance (in meters) from the first point on the left bank
river_object.plot_centerline(coordinate_unit="Relative Distance")
For more details to fix unexpected behavior or error code: Debugging, Error Handling, and Edge Cases
For a complete example script to run centerline-width: centerline_width_example_script.py with example outputs
Riverbanks can be defined here as the high-contrast boundary between active/recently-active flow and the surrounding landscape. We will be mapping the right and left bank separately
Step 1
Map the left bank using the path tool. You can zoom into the river using the scroll-wheel. Flatten the mapping projection by pressing u
. Leave the pop-up window open while you are mapping. You can erase the last point placed in a path by left-clicking. To erase a different point on the path, select the point with a right-click and then erase with a left-click and then select the last point to continue mapping downstream. To move a point, select it with a right-click. The selected point is highlighted blue, other points in the current path are highlighted red. The mapped distance downstream is shown in the measurements tab in the path tool pop-up window. When done mapping the left bank, close the pop-up window for the path
Step 2
Save the path to a .kml file by right clicking on the path in Places and selecting 'save as'. Be sure to save as a .kml and not .kmz file. It is generally good practice to do this for each new path to ensure that no work is lost if Google Earth Pro crashes
Step 3
Repeat (1) and (2) for the right bank by starting a new path
Convert two .kml files from Google Earth Pro (for the left and right bank) and export the coordinates into a csv file
kml_to_csv(left_kml: str = None,
right_kml: str = None,
flip_direction: bool = False,
csv_output: str = None)
Scripts expects data as a list of point for left and right banks:
import centerline_width
centerline_width.kml_to_csv(left_kml="leftbank.kml",
right_kml="rightbank.kml",
csv_output="data/river_coords_output.csv")
Example:
llat,llon,rlat,rlon
30.037581,-92.868569,30.037441,-92.867476
30.037613,-92.868549,30.037448,-92.867474
30.037648,-92.868546,30.037482,-92.867449
30.037674,-92.868536,30.037506,-92.867432
30.037702,-92.868533,30.037525,-92.867430
Output: A csv file data/river_coords.csv
with the headers llat, llon, rlat, rlon
Convert a text file with coordinates for a left and right bank's latitude and longitude to a csv file with columns for the left bank latitude (llat), left bank longitude (llon), right bank latitude (rlat), right bank longitude (rlon)
txt_to_csv(txt_input: str = None,
flip_direction: bool = False
Scripts expects data as a list of point for left and right banks:
import centerline_width
centerline_width.txt_to_csv(txt_input="data/river_coords.txt",
flip_direction=True)
Converts text file:
llat llon rlat rlon
30.037581 -92.868569 30.037441 -92.867476
30.037613 -92.868549 30.037448 -92.867474
30.037648 -92.868546 30.037482 -92.867449
30.037674 -92.868536 30.037506 -92.867432
30.037702 -92.868533 30.037525 -92.867430
To a CSV file:
llat,llon,rlat,rlon
30.037581,-92.868569,30.037441,-92.867476
30.037613,-92.868549,30.037448,-92.867474
30.037648,-92.868546,30.037482,-92.867449
30.037674,-92.868536,30.037506,-92.867432
30.037702,-92.868533,30.037525,-92.867430
Output: A csv file data/river_coords.csv
with the headers llat, llon, rlat, rlon
First, generate a river object to contain river data and available transformations
centerline_width.CenterlineWidth(csv_data=None,
cutoff=None,
interpolate_data=False,
interpolate_n=5,
interpolate_n_centerpoints=None,
equal_distance=10,
ellipsoid="WGS84")
Equal Distance - Equal linear distance between points
equal_distance
will generate points along the centerline that are an equal linear distance from one another in meters. When equal_distance=5
each point will be 5 meters apart
equal_distance=5 | equal_distance=20 |
---|---|
The red pins represent the equal distance centerline coordinates produced by centerline-width. The yellow line is the distance measured in Google Earth Pro between the points. The mapped river banks are in purple.
Interpolation - A solution for sparse data
interpolate_data
is an option that can be used to find a centerline when the existing data generates a Voronoi graph that is jagged or contains gaps due to the combination of sparse data and a narrow river (See: Debugging, Error Handling, and Edge Cases - Fix Gaps and Jagged Centerlines). By default, interpolate_data=True
will add 5 additional points between each existing point but can be increased or decreased by modifying the interpolate_n
option
interpolate_n_centerpoints
is an option that can be used to increase the resolution (number of points) of the centerline found by the Voronoi vertices. By default, will evenly space out to the size of the dataframe. Can artificially increase the amount of width lines generated by increasing the number of center points. When interpolate_n_centerpoints
increases, the number of width lines generated will increase (and visa versa)
interpolate_n_centerpoints=75 | interpolate_n_centerpoints=200 |
---|---|
Object (class) useful attributes:
import centerline_width
river_object = centerline_width.CenterlineWidth(csv_data="data/river_coords.csv")
Return the coordinates of the centerline based on the left and right banks with either Decimal Degree
(latitude/longitude) or Relative Distance
(meters)
Types of Centerlines
There are four types of centerline coordinates formed from the riverbank data
equal_distance=10
)
interpolate_n_centerpoints=200
)
By default, coordinates are formed in Decimal Degrees
, but can be set to Relative Distance
. Relative Distance measures the distance (in meters) of a point from the first point on the left bank
Centerline coordinates are formed by the Voronoi vertices
river_object.centerline_voronoi
river_object.centerline_voronoi | river_object.centerline_voronoi_relative |
---|---|
Centerline coordinates are formed by Equally Distanced vertices, set by equal_distance
river_object.centerline_equal_distance
river_object.centerline_equal_distance | river_object.centerline_equal_distance_relative |
---|---|
Centerline coordinates are formed by Evenly Spaced vertices, set by interpolate_n_centerpoints
river_object.centerline_evenly_spaced
river_object.centerline_evenly_spaced | river_object.centerline_evenly_spaced_relative |
---|---|
Centerline coordinates are formed from Smoothed vertices
river_object.centerline_smoothed
river_object.centerline_smoothed | river_object.centerline_smoothed_relative |
---|---|
Example:
import centerline_width
river_object = centerline_width.CenterlineWidth(csv_data="data/river_coords.csv")
river_centerline_coordinates = river_object.centerline_voronoi
Output is a list of tuples: (example) [(-92.86788596499872, 30.03786596717931), (-92.86789573751797, 30.037834641974108), (-92.8679141386283, 30.037789636848878), (-92.8679251193248, 30.037756853899904), (-92.86796903819089, 30.03765423778148), (-92.86797335733262, 30.037643336049054), (-92.8679920356456, 30.037592224469797), (-92.86800576063828, 30.037555441489403), (-92.86800841510367, 30.037546512833107), (-92.8680119498663, 30.03753043193875)]
Save the centerline coordinates to a csv file with columns for latitude and longitude. This is the file format for a table of (latitude,longitude) pairs accepted to import back into Google Earth Pro.
save_centerline_csv(save_to_csv=None, centerline_type="Voronoi", coordinate_unit="Decimal Degrees")
<centerline_type> Centerline Latitude (Deg)
or <centerline_type> Relative Distance Y (from Latitude) (m)
<centerline_type> Centerline Longitude (Deg)
or <centerline_type> Relative Distance X (from Longitude) (m)
import centerline_width
river_object = centerline_width.CenterlineWidth(csv_data="data/river_coords.csv")
river_object.save_centerline_csv(save_to_csv="centerline_coordinates.csv", centerline_type="Smoothed")
Returns a csv with the Latitude and Longitude coordinates of the specified centerline with column headers with centerline type: Smoothed Centerline Latitude (Deg), Smoothed Centerline Longitude (Deg)
[!TIP] It is best practice to plot the centerline with
plot_centerline()
to ensure that the results saved are as expected
Save the centerline coordinates to a .mat file with columns for latitude and longitude
save_centerline_mat(save_to_mat=None, centerline_type="Voronoi", coordinate_unit="Decimal Degrees")
<centerline_type>_Centerline_Latitude_(Deg)
or <centerline_type>_Relative_Distance_Y_From_Latitude_m
(cannot include spaces or special characters)<centerline_type>_Centerline_Longitude_(Deg)
or <centerline_type>_Relative_Distance_X_From_Longitude_m
(cannot include spaces or special characters)import centerline_width
river_object = centerline_width.CenterlineWidth(csv_data="data/river_coords.csv")
river_object.save_centerline_mat(save_to_mat="centerline_coordinates.mat", centerline_type="Smoothed")
Returns a .mat file with the Latitude and Longitude coordinates of the specified centerline with column headers with centerline type: Smoothed_Centerline_Latitude_(Deg), Smoothed_Centerline_Longitude_(Deg)
[!TIP] It is best practice to plot the centerline with
plot_centerline()
to ensure that the results saved are as expected
Return the length of the centerline found between the left and right bank generated by the Voronoi diagram
river_object.centerline_length
Length returned in kilometers
import centerline_width
river_object = centerline_width.CenterlineWidth(csv_data="data/river_coords.csv")
river_centerline_length = river_object.centerline_length
The length of the river centerline returns 215.34700589636674
km
Return the area contained within the polygon generated the left and right bank latitude/longitudes
river_object.area
Area returned in kilometers^2
import centerline_width
river_object = centerline_width.CenterlineWidth(csv_data="data/river_coords.csv")
river_area = river_object.area
The area of the river returns 334.0398585246558
km^2
Return the total sinuosity of the river
river_object.sinuosity
The sinuosity (or sinuosity index) is the ratio of the curved centerline and the straight distance of the river
Sinuosity = centerline length / straight distance from first/last point
Sinuosity = river length / straight line length of the river
Where sinuosity is broken in types:
Sinuosity of river based on the evenly spaced centerline coordinates
import centerline_width
river_object = centerline_width.CenterlineWidth(csv_data="data/river_coords.csv")
river_area = river_object.sinuosity
The sinuosity of the river returns as a float 1.4593141841039725
Return the incremental sinuosity of the river at evenly spaced increments
incremental_sinuosity(
incremental_points=100,
save_to_csv=None)
["Centerline Latitude Start (Deg)", "Centerline Longitude Start (Deg)", "Centerline Latitude End (Deg)", "Centerline Longitude End (Deg)", "Sinuosity"]
import centerline_width
river_object = centerline_width.CenterlineWidth(csv_data="data/river_coords.csv")
river_object.incremental_sinuosity()
Returns a dictionary with the start and end centerline coordinates and associated sinuosity {((-92.87803465419134, 30.04494734395193), (-92.87718084516158, 30.03944640478984)): 0.8164574107802118, ((-92.87714797109666, 30.03944945940497), (-92.87020323809925, 30.039886265891074)): 0.9810773013508994}
Plot the centerline created from a list of right and left banks
plot_centerline(centerline_type="Voronoi",
marker_type="line",
centerline_color="black",
dark_mode=False,
equal_axis=False,
display_all_possible_paths=False,
plot_title=None,
save_plot=None,
display_voronoi=False,
show_plot=True,
coordinate_unit="Decimal Degrees")
centerline_color="black"
to centerline_color="white"
), defaults to Falseimport centerline_width
river_object = centerline_width.CenterlineWidth(csv_data="data/river_coords.csv")
river_object.plot_centerline()
centerline_type
Display different centerline types in plot ("Voronoi", "Evenly Spaced", "Smoothed", "Equal Distance"), but defaults to "Voronoi"
centerline_type="Voronoi" | centerline_type="Smoothed" |
---|---|
marker_type
Display centerline plot as either line or scatter
marker_type="Line" | marker_type="Scatter" |
---|---|
centerline_color
Change the color of the centerline, defaults to black
centerline_color="black" | centerline_color="palegreen" |
---|---|
dark_mode
dark_mode will change the default Matplotlib background black and swap centerline_color
from default black to white
dark_mode=False | dark_mode=True |
---|---|
equal_axis
equal_axis will set the x and y axis of the plot to be equal
equal_axis=False | equal_axis=True |
---|---|
display_all_possible_paths
Display all possible paths generated by Voronoi edge ridges, defaults to False
display_all_possible_paths=False | display_all_possible_paths=True |
---|---|
display_voronoi
Overlay Voronoi diagram used to generate centerline, defaults to False
display_voronoi=False | display_voronoi=True |
---|---|
coordinate_unit
Plot as either "Decimal Degrees" and "Relative Distance". defaults to "Decimal Degrees"
coordinate_unit="Decimal Degrees" | coordinate_unit="Relative Distance" |
---|---|
Plot the width of the river based on the centerline
plot_centerline_width(plot_title=None,
save_plot=None,
display_true_centerline=True,
transect_span_distance=3,
transect_slope="Average",
apply_smoothing=False,
flag_intersections=True,
remove_intersections=False,
dark_mode=False,
equal_axis=False,
show_plot=True,
coordinate_unit="Decimal Degrees")
centerline_color="black"
to centerline_color="white"
), defaults to Falseimport centerline_width
river_object = centerline_width.CenterlineWidth(csv_data="data/river_coords.csv")
river_object.plot_centerline_width(apply_smoothing=True, remove_intersections=True, display_true_centerline=False)
display_true_centerline
The width lines are generated from the evenly spaced coordinate (by default) or with the smoothed coordinates (when apply_smoothing=True
), but display_true_centerline will overlay the Voronoi centerline on top of the plot
display_true_centerline=True | display_true_centerline=False |
---|---|
apply_smoothing
apply_smoothing applies a spline to smooth the centerline points created by the Voronoi vertices. This reduces the noise of the slopes and can create width lines that are less susceptible to small changes in the bank
apply_smoothing=False | apply_smoothing=True |
---|---|
transect_span_distance
Transect span describes the number of points that are averaged to generate the slope of the width line (example: transect_span_distance=3, average of three slopes). The slope of the width line is orthogonal to the average slopes measured along the transect span
If the span is odd then the width line will be generated at the position of the middle of the span on n/2. If the span is even, then the width line will be generated at 1 + n/2, for example, [A, B, C, D]
will generated a width line at point C
transect_span_distance=6 | transect_span_distance=30 |
---|---|
transect_slope
The width lines are generated as perpendicular to the slopes of the points across transect_span_distance
By default, transect_slope="Average"
where the width lines are perpendicular to the average slopes of the across span distance. For example: [A, B, C, D] = avg( slope([A, B]) + slope([B, C]) + slope([C+D]) )
Optionally, if transect_slope="Direct"
then the width lines will be perpendicular to slope of the first and last point. For example: [A, B, C, D] = slope([A, D])
to avoid being susceptible to rapid small changes along the centerline
transect_slope="Average" | transect_slope="Direct" |
---|---|
remove_intersections
remove_intersections will remove the width lines that intersect other lines (that could be creating unrepresentative long width lines). Intersections are removed first in order from most to least number of intersections and then based on the longer of two intersecting lines. This ensures that the most width lines as possible are kept
Intersecting lines are flagged in red by default (flag_intersections=True)
remove_intersections=False | remove_intersections=True |
---|---|
dark_mode
dark_mode will change the default Matplotlib background black and swap centerline_color
from default black to white
dark_mode=False | dark_mode=True |
---|---|
equal_axis
equal_axis will set the x and y axis of the plot to be equal. Useful to show the perpendicular width lines as perpendicular since it can appear distorted by default in Matplotlib
equal_axis=False | equal_axis=True |
---|---|
coordinate_unit
Two options for measuring and displaying coordinates. The two options are "Decimal Degrees" and "Relative Distance". "Decimal Degrees" is the default option that uses the original data coordinate system with latitude/longitude. "Relative Distance" changes the coordinates of each point to be the distance (in meters) from the first point on the left bank
coordinate_unit="Decimal Degrees" | coordinate_unit="Relative Distance" |
---|---|
Return the width of the river at each (evenly spaced or smoothed) with coordinates where width line intersects either the centerline, (Centerline Longitude, Centerline Latitude) : width
, or riverbanks, ((Right Bank Longitude, Right Bank Latitude), (Left Bank Longitude, Left Bank Latitude)) : width
in kilometers
width(transect_span_distance=3,
transect_slope="Average",
apply_smoothing=True,
remove_intersections=False,
coordinate_unit="Decimal Degrees",
coordinate_reference="Centerline",
save_to_csv=None)
(Centerline Longitude, Centerline Latitude) : width
, or riverbanks ("Banks") as ((Right Bank Longitude, Right Bank Latitude), (Left Bank Longitude, Left Bank Latitude)) : width
coordinate_unit
and coordinate_reference
)[!IMPORTANT] When using
apply_smoothing=True
, the centerline generated is the result of evenly spaced coordinates generated from the original Voronoi coordinates, so the smoothed coordinates may not match exactly to the original centerline coordinates. Whenapply_smoothing=False
, width lines are generated from the evenly spaced centerline coordinates
import centerline_width
river_object = centerline_width.CenterlineWidth(csv_data="data/river_coords.csv")
river_width_dict = river_object.width(transect_span_distance=3,
apply_smoothing=True,
coordinate_reference="Centerline",
remove_intersections=True)
Width dictionary = {(-92.86792084788995, 30.037769672351182): 0.10969163557087018, (-92.86795038641004, 30.03769867854198): 0.10794219579997719}
[!TIP] It is best practice to plot the centerline and width with same arguments in
plot_centerline_width()
to ensure that the results whensave_to_csv=True
are as expected
The centerline is defined by the greatest distance from the right and left bank, created from a Voronoi Diagram. The remaining paths within the river are filtered through Dijkstra's algorithm to find the shortest path that is the centerline
Filter out any point pairs that only have one connection to filter out the short dead end paths
With the vertices removed, it is possible to form multiple unconnected graphs within the polygon. The largest subgraph is assumed to contain the centerline and the other subgraphs are filtered out
The top of the river is defined as the last plotted points in the data, while the bottom of the river is the first plotted points
The starting/ending node is defined by the vertex closest to the top/bottom of the polygon along the longest path
Points on Riverbank | NetworkX Graph of Points on Riverbank |
---|---|
This is an attempt at a more robust algorithm working from raw data to ensure that all dead ends are removed, and no gaps exist in the centerline
Points that only have one connection are removed, but limiting the number of connections for a point to just two will create gaps. The Voronoi vertices connect to other vertex values, but some connect to more and some only connect to one other point. Removing additional values will create gaps, so this is avoided in this code by not applying additional filters.
All vertices:
Vertices that have at least two connections (that would create gaps):
If the data starts or ends with a large width, it is possible for the starting/ending nodes to end up in the wrong position Currently, the starting node is determined by the closest node on the path to the top of the bank (in green) and the ending node is determined by the closest node on the path to the bottom of the bank (in red) that sits along the longest path
A polygon is formed to encapsulate the river with the given data (to determine the inside and outside of the river). The top and bottom are connected by a straight line from the start/end of the available data. As a result, it is possible for this straight line to overlap and create an invalid polygon.
A polygon is invalid if it overlaps within itself: In this example, the polygon is invalid, but with such a small overlap it is still able to find a valid path
With limited data, the polygon will overlap more dramatically and will struggle to find a valid centerline:
If the data is too small, a centerline and its coordinates cannot be found (since only a single Voronoi vertex exists within the polygon and after dead ends are filtered)
CRITICAL ERROR, Polygon too short for the Voronoi diagram generated (no starting node found), unable to plot centerline. Set display_voronoi=True to view vertices. Can typically be fixed by adding more data to expand range
Can be fixed by expanding the data until the polygon is large enough to contain at least two different vertex points
Error: WARNING: Invalid Polygon Due to Flipped Banks, fix recommendation: rerun convertColumnsToCSV() and set flip_direction=True (or reset to default 'False' if currently set to flip_direction=True)
If the data for the left and right riverbanks are generated in reverse order, they will be read in the incorrect order and the graph will find the invalid top and bottom of the bank
If the latitude/longitude of the banks are generated in reverse order, flip the final values so left/right bank are in order
This can be fixed by using the flip_direction optional argument centerline_width.convertColumnsToCSV(text_file="data_example.txt", flip_direction=True)
The smoothed centerline (river_object.centerline_smoothed
) can end up lying outside the river if the centerline data points are sparse in a narrow river. If more than two points in the smoothed centerline lie outside the river, a warning will be thrown
Example Error: WARNING: Partially invalid smoothed centerline due to sparse centerline data (6 points lie outside the polygon), fix recommendation: rerun CenterlineWidth to create river object with interpolate_n_centerpoints set to 62+
By default, interpolate_n_centerpoints
is set to None and no additional points will be added between the existing points along the centerline. By adding additional points between the existing centerline, the smoothed centerline can be fixed to stay within the polygon. This fix is set by creating a river object, centerline_width.CenterlineWidth
, with interpolate_n_centerpoints=65
(with the recommended 62+) to fix for centerline coordinates that lie outside the polygon
interpolate_n_centerpoints = None
does not interpolate data points, so the size will be set to the number of fixed points when creating the evenly spaced coordinates (equal to the size of the data frame)
interpolate_n_centerpoints = None | interpolate_n_centerpoints = 65 |
---|---|
For very narrow rivers, this problem can become extreme and pronounced
By increasing the interpolation between the centerline points, the smoothed centerlines will be forced within the polygon and reduce the number of points outside of the polygon. By default, this warning will be thrown if more than 2 points are outside of polygon, so as long as more than 2 points lie outside the polygon, the warning will recommend doubling the amount of centerline points, with diminishing returns
Gaps formed can cause part of the centerline to be skipped due to sparse data. As a result, the start and end of the centerline can skip parts at the beginning or end of a river
Set river object created by centerline_width.CenterlineWidth
to interpolate_data=True
to fix for jagged edges or gaps formed by the interaction of sparse data and narrow banks
river_object = centerline_width.CenterlineWidth(csv_data="data/river_coords.csv", interpolate_data=True)
interpolate_data = False | interpolate_data = True |
---|---|
The number of additional points added by interpolating can be adjusted with interpolate_n
, but defaults to add 5 additional points between values
To run or test against centerline-width
github repo/fork, a development environment can be created via conda/miniconda
First, install Miniconda
Then, using the existing environment.yml
, a new conda environment can be create to run/test scripts against
conda env create --file environment.yml
Once the environment has been built, activate the environment:
conda activate centerline_width
Set up pre-commit hooks to ensure standard code formatting and spelling:
pre-commit install
Pre-commit hooks can be manually run before commits:
pre-commit run --all-files
To run existing and new tests from the root directory:
python -m pytest
These features are not included in pip install because they are still experimental and being tested/debugged. For more information and getting them up and running, contact cyschneck@gmail.com or ugschneck@gmail.com or post a question as a Github Issue
Calculate the dominant meander wavelength amd its variance
Research and Contribute to OpenStreetMap for existing mapped rivers with generated centerlines
Calculate the asymmetry of the meanders
Calculate the dominant submeander and supermeander scales
Extract elevation/slope from river profiles (.kml files)
Overlay plots with images via geopandas
Calculate centerline migration rate
Originally, centerline-width was developed as a Python implementation of R-Code CMGO (Golly et al. 2017) but has since been extensively expanded and changed:
Golly, A. and Turowski, J. M.: Deriving principal channel metrics from bank and long-profile geometry with the R package cmgo, Earth Surf. Dynam., 5, 557-570, https://doi.org/10.5194/esurf-5-557-2017, 2017.
Please acknowledge the use of this software in any publications:
"River centerline/width extraction software was provided by C. Y. Schneck and U. G. Schneck, and is available at URL: https://github.com/cyschneck/centerline-width."
We are interested in expanding this software based on river needs, so please send a copy of such publications to: cyschneck@gmail.com and ugschneck@gmail.com (we'd love to see them!)
This material is based upon work supported by the National Science Foundation Graduate Fellowship under Grant No. 2141064. Any opinions, findings, and conclusions or recommendations expressed in this material are those of the authors and do not necessarily reflect the views of the National Science Foundation.
Submit a bug fix, question, or feature request as a Github Issue or to ugschneck@gmail.com/cyschneck@gmail.com
FAQs
A Python package to find the centerline and width of rivers based on the latitude and longitude of the right and left bank
We found that centerline-width demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.