Giter VIP home page Giter VIP logo

glacier_lengths's Introduction

glacier_lengths — Statistical glacier length calculations

build pypi Documentation Status

PyPI version fury.io

Conda Version Conda Downloads Conda Platforms

Often when glacier lengths are calculated, only the glacier centerline is considered. This is arguably not a statistically representative measure for the entire front, as it just considers one point on the glacier outline. The glacier_lengths package aims to simplify length calculations along an arbitrary amount of lines buffered around the glacier centerline.

Installation

pip install glacier_lengths

pip install git+https://github.com/erikmannerfelt/glacier_lengths.git

Documentation

See the documentation at https://glacier-lengths.readthedocs.io

Example

Calculate the length change of Rhonegletscher:

import geopandas as gpd
import glacier_lengths

# Read the example data
outlines = gpd.read_file("examples/rhone/data/outlines.shp").sort_values("year")
old_outline = outlines.iloc[0]
new_outline = outlines.iloc[1]
centerline = gpd.read_file("examples/rhone/data/centerline.shp").iloc[0]

# Generate ~40 buffered lines around the glacier centerline
old_buffered_lines = glacier_lengths.buffer_centerline(centerline.geometry, old_outline.geometry)
# Cut the newly generated lines to the new_outline
new_buffered_lines = glacier_lengths.cut_centerlines(old_buffered_lines, new_outline.geometry)

# Measure the lengths of the old and new glacier centerlines.
old_lengths = glacier_lengths.measure_lengths(old_buffered_lines)
new_lengths = glacier_lengths.measure_lengths(new_buffered_lines)

# Print the results.
print(f"""
{old_outline['year']}: {old_lengths.mean():.1f}±{old_lengths.std():.1f} m
{new_outline['year']}: {new_lengths.mean():.1f}±{new_lengths.std():.1f} m
""")

prints:

1928: 10783.6±38.8 m
2020: 9699.9±7.6 m

Plot a figure

python examples/rhone/plot_rhone.py

Testing

Run python -m pytest in the cloned repo base directory.

glacier_lengths's People

Contributors

erikmannerfelt avatar

Stargazers

bwbj avatar Adrien Wehrlé  avatar

Watchers

 avatar

Forkers

trellixvulnteam

glacier_lengths's Issues

Add modifiable minimum distance threshold in `cut_centerlines()`

At one glacier, I had the issue that the cut buffered centerlines are so short relative to the original centerline that it automatically gets filtered away. Here's the problematic line:

distance_threshold = longest_centerline.length * 0.2

The result is this:
image

The cut lines (red) west of the main centerline are filtered away because they are shorter than 80% of the original centerline. With a manually changed threshold of 0.4 instead of 0.2, it looks much better:
image

The filtering is still required as larger glaciers' buffered centerlines should never be 40% shorter than the main, but for small glaciers, it may very well be necessary.

The proposed change is to simply make it an optional argument.

Cut the buffered centerlines using a perpendicular line to the start, instead of cutting by a glacier polygon

In many cases, a glacier centerline may not end at rock (i.e. the edge of a polygon):

  • On ice caps
  • On ice sheets
  • If a reliable glacier outline does not exist and the user only wants the length compared to the start of the centerline

An outline is currently required for buffering centerlines, but that is not the only way that one can trim the buffers correctly.

Instead of cutting the buffers with a glacier outline, a perpendicular cut-line to the centerline can be drawn instead. A good example using shapely is shown here:

https://stackoverflow.com/questions/57065080/draw-perpendicular-line-of-fixed-length-at-a-point-of-another-line

Then, the buffer_centerlines function should not require an outline; either making it optional or removing it altogether.

`cut_centerlines` fails if the cut-geometry is a `MultiLineString`

In some cases, a glacier terminus position may be split up in multiple parts. For example, this might be to avoid areas of snow cover that would mess with the outline delineation. Currently, providing a MultiLineString simply fails, so each part has to be evaluated separately. It would be simpler to just allow MultiLineStrings and include functionality for it.

Add flag to remove non-cut centerlines in `cut_centerlines`

Currently, if one or more (buffered) centerlines are not cut by the cutting geometry, a warning is triggered by default. This is nice, as the user is alerted of the problem, but this is not a fix per se. A better way is to add a flag (that could be on by default) that will remove all lines that do not intersect the cut geometry. I wrote some code that easily does this:

lines_cut = []
for i, centerline_buf in enumerate(centerlines_buffered.geoms):                                          
    if not centerline_buf.intersects(outline):                          
        continue                                                        
                                                                                        
    line_cut = glacier_lengths.cut_centerlines(centerline_buf, outline)
    lines_cut.append(line_cut)

It's basically just the intersection check that is an addition to the current functionality, but it opens a few doors:

  • The returned lines will always be representative.
  • A large buffer radius can be specified, and the cutting step automatically helps narrow down the lines to a sensible width.

Add option to keep track of centerline indices when cutting them and measuring lengths

To measure length differences, the mean length of one year can be subtracted to another. When measuring the spread, however, it is better to do an element-wise subtraction (each element being a buffered centerline's length) and deriving the spread of that. This requires some way of keeping track of the index of each centerline. As far as I'm aware, the order of LineStrings in the MultiLineString from buffer_centerlines() is kept when cutting, but this is not a guarantee unless there's a check for it, and #12 would mess with the order.

One potential solution would be to allow a dictionary as the centerlines in cut_centerlines(). For example:

>>> centerlines = {0: LineString(...), 1: LineString(...)}
>>> glacier_lengths.cut_centerlines(centerlines, cut_geometry)
{1: LineString(...)}

Here, I assume that #12 is implemented, and that centerline "0" was deemed invalid in some way, such as that it didn't intersect the cut-geometry.

Add warning if cutting geometry does not cut all centerlines

If a glacier outline only cuts a few centerlines, it will register a length that is too high. A warning should be issued in that case.

This may happen if for example a glacier outline is very short, and doesn't cover the buffer around the centerline.

Shapely deprecation warnings in recent shapely versions

In shapely 1.8, some terminology was introduced and old terminology was deprecated, and will stop working completely in shapely 2.0. More specifically, multi-part geometries should now be iterated over with the .geoms property.

The result of the deprecation is now that lots of warnings show up, mostly originating from the glacier_lengths.core.iter_geom() convenience function. The solution is probably just fixing that function to use the new terminology, and adding a test to show that no warnings are present.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.