def test_init_errors():
    with pytest.raises(ValueError, match='lines must be a GeoSeries'):
        swn.SurfaceWaterNetwork(object())
    with pytest.raises(ValueError, match='lines must be a GeoSeries'):
        swn.SurfaceWaterNetwork(valid_df)
    with pytest.raises(ValueError, match='one or more lines are required'):
        swn.SurfaceWaterNetwork(valid_lines[0:0])
def test_remove_segnums():
    n = swn.SurfaceWaterNetwork(valid_lines)
    assert len(n) == 3
    n.remove(segnums=[1])
    assert len(n) == 2
    assert len(n.segments) == 2
    assert list(n.segments.index) == [0, 2]
    assert n.segments.at[0, 'from_segnums'] == set([1, 2])
    # repeats are ok
    n = swn.SurfaceWaterNetwork(valid_lines)
    n.remove(segnums=[1, 2, 1])
    assert len(n) == 1
    assert len(n.segments) == 1
    assert list(n.segments.index) == [0]
    assert n.segments.at[0, 'from_segnums'] == set([1, 2])
def test_init_mismatch_3D():
    # Match in 2D, but not in Z dimension
    lines = wkt_to_geoseries([
        'LINESTRING Z (70 130 15, 60 100 14)',
        'LINESTRING Z (60 100 14, 60  80 12)',
        'LINESTRING Z (40 130 15, 60 100 13)',
    ])
    n = swn.SurfaceWaterNetwork(lines)
    assert len(n.warnings) == 1
    assert n.warnings[0] == \
        'end of segment 2 matches start of segment 1 in 2D, but not in '\
        'Z dimension'
    assert len(n.errors) == 0
    assert len(n) == 3
    assert n.has_z is True
    assert list(n.segments.index) == [0, 1, 2]
    assert repr(n) == dedent('''\
        <SurfaceWaterNetwork: with Z coordinates
          3 segments: [0, 1, 2]
          2 headwater: [0, 2]
          1 outlets: [1]
          no diversions />''')
    if matplotlib:
        _ = n.plot()
        plt.close()
def test_catchments_property():
    # also vary previous test with 2D lines
    n = swn.SurfaceWaterNetwork(force_2d(valid_lines))
    assert n.catchments is None
    n.catchments = valid_polygons
    assert n.catchments is not None
    np.testing.assert_array_almost_equal(
            n.catchments.area, [800.0, 875.0, 525.0])
    np.testing.assert_array_almost_equal(
            n.segments['upstream_area'], [2200.0, 875.0, 525.0])
    np.testing.assert_array_almost_equal(
            n.segments['width'], [1.4615, 1.4457, 1.4397], 4)
    assert repr(n) == dedent('''\
        <SurfaceWaterNetwork: with catchment polygons
          3 segments: [0, 1, 2]
          2 headwater: [1, 2]
          1 outlets: [0]
          no diversions />''')
    if matplotlib:
        _ = n.plot()
        plt.close()
    # unset property
    n.catchments = None
    assert n.catchments is None
    # check errors
    with pytest.raises(
            ValueError,
            match='catchments must be a GeoSeries or None'):
        n.catchments = 1.0
    with pytest.raises(
            ValueError,
            match=r'catchments\.index is different than for segments'):
        n.catchments = valid_polygons.iloc[1:]
def test_catchment_polygons(coastal_lines_gdf, coastal_polygons_gdf):
    lines = coastal_lines_gdf.geometry
    polygons = coastal_polygons_gdf.geometry
    n = swn.SurfaceWaterNetwork(lines, polygons)
    cat_areas = n.catchments.area
    # only consider areas where polygons existed (some were filled in)
    nonzero = coastal_polygons_gdf['Area'] != 0.0
    np.testing.assert_allclose(cat_areas[nonzero],
                               coastal_polygons_gdf.loc[nonzero, 'Area'])
    # this has a wider margin of error, but still relatively small
    up_cat_areas = n.accumulate_values(cat_areas)
    np.testing.assert_allclose(up_cat_areas,
                               coastal_lines_gdf['CUM_AREA'],
                               atol=7800.0)
    ua = n.segments['upstream_area']
    np.testing.assert_almost_equal(ua.min(), 180994.763, 3)
    np.testing.assert_almost_equal(ua.mean(), 7437127.120, 3)
    np.testing.assert_almost_equal(ua.max(), 100625129.836, 3)
    w = n.segments['width']
    np.testing.assert_almost_equal(w.min(), 1.831, 3)
    np.testing.assert_almost_equal(w.mean(), 3.435, 3)
    np.testing.assert_almost_equal(w.max(), 12.420, 3)
    assert repr(n) == dedent('''\
        <SurfaceWaterNetwork: with Z coordinates and catchment polygons
          304 segments: [3046409, 3046455, ..., 3050338, 3050418]
          154 headwater: [3046409, 3046542, ..., 3050338, 3050418]
          3 outlets: [3046700, 3046737, 3046736]
          no diversions />''')
    if matplotlib:
        _ = n.plot()
        plt.close()
def test_init_2D_geom():
    lines = force_2d(valid_lines)
    n = swn.SurfaceWaterNetwork(lines)
    assert len(n.warnings) == 0
    assert len(n.errors) == 0
    assert len(n) == 3
    assert n.has_z is False
    assert list(n.segments.index) == [0, 1, 2]
    assert list(n.segments['to_segnum']) == [-1, 0, 0]
    assert list(n.segments['cat_group']) == [0, 0, 0]
    assert list(n.segments['num_to_outlet']) == [1, 2, 2]
    np.testing.assert_allclose(
        n.segments['dist_to_outlet'], [20.0, 56.05551, 51.622776])
    assert list(n.segments['sequence']) == [3, 1, 2]
    assert list(n.segments['stream_order']) == [2, 1, 1]
    np.testing.assert_allclose(
        n.segments['upstream_length'], [87.67828936, 36.05551275, 31.6227766])
    assert list(n.headwater) == [1, 2]
    assert list(n.outlets) == [0]
    assert repr(n) == dedent('''\
        <SurfaceWaterNetwork:
          3 segments: [0, 1, 2]
          2 headwater: [1, 2]
          1 outlets: [0]
          no diversions />''')
    if matplotlib:
        _ = n.plot()
        plt.close()
def test_init_line_connects_to_middle():
    lines = wkt_to_geoseries([
        'LINESTRING Z (40 130 15, 60 100 14, 60 80 12)',
        'LINESTRING Z (70 130 15, 60 100 14)',
    ])
    n = swn.SurfaceWaterNetwork(lines)
    assert len(n.warnings) == 0
    assert len(n.errors) == 1
    assert n.errors[0] == 'segment 1 connects to the middle of segment 0'
    assert len(n) == 2
    assert n.has_z is True
    assert list(n.segments.index) == [0, 1]
    assert list(n.segments['to_segnum']) == [-1, -1]
    assert list(n.segments['cat_group']) == [0, 1]
    assert list(n.segments['num_to_outlet']) == [1, 1]
    np.testing.assert_allclose(
        n.segments['dist_to_outlet'], [56.05551, 31.622776])
    assert list(n.segments['sequence']) == [1, 2]
    assert list(n.segments['stream_order']) == [1, 1]
    np.testing.assert_allclose(
        n.segments['upstream_length'], [56.05551, 31.622776])
    assert list(n.headwater) == [0, 1]
    assert list(n.outlets) == [0, 1]
    assert dict(n.to_segnums) == {}
    assert n.from_segnums == {}
    assert repr(n) == dedent('''\
        <SurfaceWaterNetwork: with Z coordinates
          2 segments: [0, 1]
          2 headwater: [0, 1]
          2 outlets: [0, 1]
          no diversions />''')
    if matplotlib:
        _ = n.plot()
        plt.close()
def test_remove_condition():
    n = swn.SurfaceWaterNetwork(valid_lines, valid_polygons)
    assert len(n) == 3
    # manually copy these, to compare later
    n.segments['orig_upstream_length'] = n.segments['upstream_length']
    n.segments['orig_upstream_area'] = n.segments['upstream_area']
    n.segments['orig_width'] = n.segments['width']
    n.remove(n.segments['upstream_area'] <= 1000.0)
    assert len(n) == 1
    assert len(n.segments) == 1
    assert len(n.catchments) == 1
    assert list(n.segments.index) == [0]
    assert n.segments.at[0, 'from_segnums'] == set([1, 2])
    np.testing.assert_almost_equal(
        n.segments.at[0, 'upstream_length'], 87.67828936)
    np.testing.assert_almost_equal(
        n.segments.at[0, 'upstream_area'], 2200.0)
    np.testing.assert_almost_equal(
        n.segments.at[0, 'width'], 1.4615, 4)
    # Manually re-trigger these
    n.evaluate_upstream_length()
    n.evaluate_upstream_area()
    n.estimate_width()
    np.testing.assert_almost_equal(
        n.segments.at[0, 'upstream_length'], 20.0)
    np.testing.assert_almost_equal(
        n.segments.at[0, 'upstream_area'], 800.0)
    np.testing.assert_almost_equal(
        n.segments.at[0, 'width'], 1.4445, 4)
    np.testing.assert_almost_equal(
        n.segments.at[0, 'orig_upstream_length'], 87.67828936)
    np.testing.assert_almost_equal(
        n.segments.at[0, 'orig_upstream_area'], 2200.0)
    np.testing.assert_almost_equal(
        n.segments.at[0, 'orig_width'], 1.4615, 4)
def test_adjust_elevation_profile_no_change():
    lines = wkt_to_geoseries(['LINESTRING Z (0 0 8, 1 0 7, 2 0 6)'])
    n = swn.SurfaceWaterNetwork(lines)
    n.adjust_elevation_profile()
    assert len(n.messages) == 0
    assert (lines == n.segments.geometry).all()
    expected_profiles = wkt_to_geoseries(['LINESTRING (0 8, 1 7, 2 6)'])
    assert (n.profiles == expected_profiles).all()
def test_estimate_width():
    n = swn.SurfaceWaterNetwork(valid_lines, valid_polygons)
    # defaults
    np.testing.assert_array_almost_equal(
            n.segments['width'], [1.4615, 1.4457, 1.4397], 4)
    # float a and b
    n.estimate_width(1.4, 0.6)
    np.testing.assert_array_almost_equal(
            n.segments['width'], [1.4254, 1.4146, 1.4108], 4)
    # integer a and b
    n.estimate_width(1, 1)
    np.testing.assert_array_almost_equal(
            n.segments['width'], [1.0022, 1.0009, 1.0005], 4)
    # a and b are Series per segment
    n.estimate_width([1.2, 1.8, 1.4], [0.4, 0.7, 0.6])
    np.testing.assert_array_almost_equal(
            n.segments['width'], [1.2006, 1.8, 1.4], 4)
    # based on Series
    n.estimate_width(upstream_area=n.segments['upstream_area'] / 2)
    np.testing.assert_array_almost_equal(
            n.segments['width'], [1.4489, 1.4379, 1.4337], 4)
    # defaults (again)
    n.estimate_width()
    np.testing.assert_array_almost_equal(
            n.segments['width'], [1.4615, 1.4457, 1.4397], 4)
    # based on a column, where upstream_area is not available
    n2 = swn.SurfaceWaterNetwork(valid_lines)
    assert 'width' not in n2.segments.columns
    assert 'upstream_area' not in n2.segments.columns
    n2.segments['foo_upstream'] = n2.segments['upstream_length'] * 25
    n2.estimate_width(upstream_area='foo_upstream')
    np.testing.assert_array_almost_equal(
            n2.segments['width'], [1.4614, 1.4461, 1.4444], 4)
    # check errors
    with pytest.raises(
            ValueError,
            match='unknown use for upstream_area'):
        n.estimate_width(upstream_area=3)
    with pytest.raises(
            ValueError,
            match=r"'upstream_area' not found in segments\.columns"):
        n2.estimate_width()
def test_init_geoseries():
    gs = wkt_to_geoseries(valid_lines_list, geom_name='foo')
    n = swn.SurfaceWaterNetwork(gs)
    assert len(n.warnings) == 0
    assert len(n.errors) == 0
    assert len(n) == 3
    assert list(n.segments.index) == [0, 1, 2]
    assert n.has_z is True
    v = pd.Series([3.0, 2.0, 4.0])
    a = n.accumulate_values(v)
    assert dict(a) == {0: 9.0, 1: 2.0, 2: 4.0}
def test_adjust_elevation_profile_use_min_slope():
    lines = wkt_to_geoseries(['LINESTRING Z (0 0 8, 1 0 9)'])
    n = swn.SurfaceWaterNetwork(lines)
    n.adjust_elevation_profile()
    n.profiles = round_coords(n.profiles)
    n.segments.geometry = round_coords(n.segments.geometry)
    assert len(n.messages) == 1
    assert n.messages[0] == \
        'segment 0: adjusted 1 coordinate elevation by 1.001'
    expected = wkt_to_geoseries(['LINESTRING Z (0 0 8, 1 0 7.999)'])
    assert (expected == n.segments.geometry).all()
    expected_profiles = wkt_to_geoseries(['LINESTRING (0 8, 1 7.999)'])
    assert (n.profiles == expected_profiles).all()

    lines = wkt_to_geoseries(['LINESTRING Z (0 0 8, 1 0 9, 2 0 6)'])
    n = swn.SurfaceWaterNetwork(lines)
    n.adjust_elevation_profile(0.1)
    assert len(n.messages) == 1
    assert n.messages[0] == \
        'segment 0: adjusted 1 coordinate elevation by 1.100'
    expected = wkt_to_geoseries(['LINESTRING Z (0 0 8, 1 0 7.9, 2 0 6)'])
    assert (expected == n.segments.geometry).all()
    expected_profiles = wkt_to_geoseries(['LINESTRING (0 8, 1 7.9, 2 6)'])
    assert (n.profiles == expected_profiles).all()

    lines = wkt_to_geoseries(['LINESTRING Z (0 0 8, 1 0 5, 2 0 6, 3 0 5)'])
    n = swn.SurfaceWaterNetwork(lines)
    n.adjust_elevation_profile(0.2)
    assert len(n.messages) == 1
    assert n.messages[0] == \
        'segment 0: adjusted 2 coordinate elevations between 0.400 and 1.200'
    expected = wkt_to_geoseries(
            ['LINESTRING Z (0 0 8, 1 0 5, 2 0 4.8, 3 0 4.6)'])
    assert (expected == n.segments.geometry).all()
    expected_profiles = wkt_to_geoseries(
            ['LINESTRING (0 8, 1 5, 2 4.8, 3 4.6)'])
    assert (n.profiles == expected_profiles).all()
def test_init_polygons():
    expected_area = [800.0, 875.0, 525.0]
    expected_upstream_area = [2200.0, 875.0, 525.0]
    expected_upstream_width = [1.4615, 1.4457, 1.4397]
    # from GeoSeries
    n = swn.SurfaceWaterNetwork(valid_lines, valid_polygons)
    assert n.catchments is not None
    np.testing.assert_array_almost_equal(n.catchments.area, expected_area)
    np.testing.assert_array_almost_equal(
            n.segments['upstream_area'], expected_upstream_area)
    np.testing.assert_array_almost_equal(
            n.segments['width'], expected_upstream_width, 4)
    # from GeoDataFrame
    n = swn.SurfaceWaterNetwork(valid_lines, valid_polygons)
    assert n.catchments is not None
    np.testing.assert_array_almost_equal(n.catchments.area, expected_area)
    np.testing.assert_array_almost_equal(
            n.segments['upstream_area'], expected_upstream_area)
    np.testing.assert_array_almost_equal(
            n.segments['width'], expected_upstream_width, 4)
    # manual upstream area calculation
    np.testing.assert_array_almost_equal(
        n.accumulate_values(n.catchments.area), expected_upstream_area)
    assert repr(n) == dedent('''\
        <SurfaceWaterNetwork: with Z coordinates and catchment polygons
          3 segments: [0, 1, 2]
          2 headwater: [1, 2]
          1 outlets: [0]
          no diversions />''')
    if matplotlib:
        _ = n.plot()
        plt.close()
    # check error
    with pytest.raises(
            ValueError,
            match='polygons must be a GeoSeries or None'):
        swn.SurfaceWaterNetwork(valid_lines, 1.0)
Ejemplo n.º 14
0
def test_init_segments_loc():
    lines = wkt_to_geoseries([
        "LINESTRING (60 100, 60  80)",
        "LINESTRING (40 130, 60 100)",
        "LINESTRING (70 130, 60 100)",
        "LINESTRING (60  80, 70  70)",
    ])
    lines.index += 100
    n1 = swn.SurfaceWaterNetwork.from_lines(lines)
    assert list(n1.outlets) == [103]
    # Create by slicing another GeoDataFrame, but check to_segnums
    n2 = swn.SurfaceWaterNetwork(n1.segments.loc[100:102])
    assert len(n2.segments) == 3
    assert list(n2.outlets) == [100]
    assert dict(n2.to_segnums) == {101: 100, 102: 100}
def test_adjust_elevation_profile_errors(valid_n):
    with pytest.raises(
            ValueError,
            match='min_slope must be greater than zero'):
        valid_n.adjust_elevation_profile(0.0)

    n2d = swn.SurfaceWaterNetwork(force_2d(valid_lines))
    with pytest.raises(
            AttributeError,
            match='line geometry does not have Z dimension'):
        n2d.adjust_elevation_profile()

    min_slope = pd.Series(2./1000, index=valid_n.segments.index)
    min_slope[1] = 3./1000
    min_slope.index += 1
    with pytest.raises(ValueError, match='index is different'):
        valid_n.adjust_elevation_profile(min_slope)
def test_init_all_diverge():
    # Lines all diverge from the same place
    lines = wkt_to_geoseries([
        'LINESTRING Z (60 100 15, 40 130 14)',
        'LINESTRING Z (60 100 16, 70 130 14)',
        'LINESTRING Z (60 100 15, 60  80 12)',
    ])
    n = swn.SurfaceWaterNetwork(lines)
    assert len(n.warnings) == 4
    assert n.warnings[0] == \
        'starting segment 0 matches start of segment 1 in 2D, '\
        'but not in Z dimension'
    assert len(n.errors) == 1
    assert n.errors[0] == \
        'starting coordinate (60.0, 100.0) matches start segments: ' + \
        str(set([0, 1, 2]))
    assert len(n) == 3
    assert n.has_z is True
    assert list(n.segments.index) == [0, 1, 2]
    assert list(n.segments['to_segnum']) == [-1, -1, -1]
    assert list(n.segments['num_to_outlet']) == [1, 1, 1]
    assert list(n.segments['cat_group']) == [0, 1, 2]
    np.testing.assert_allclose(
        n.segments['dist_to_outlet'], [36.05551, 31.622776, 20.0])
    assert list(n.segments['sequence']) == [1, 2, 3]
    assert list(n.segments['stream_order']) == [1, 1, 1]
    np.testing.assert_allclose(
        n.segments['upstream_length'], [36.05551, 31.622776, 20.0])
    assert list(n.headwater) == [0, 1, 2]
    assert list(n.outlets) == [0, 1, 2]
    assert dict(n.to_segnums) == {}
    assert n.from_segnums == {}
    assert repr(n) == dedent('''\
        <SurfaceWaterNetwork: with Z coordinates
          3 segments: [0, 1, 2]
          3 headwater: [0, 1, 2]
          3 outlets: [0, 1, 2]
          no diversions />''')
    if matplotlib:
        _ = n.plot()
        plt.close()
def test_set_diversions_dataframe():
    n = swn.SurfaceWaterNetwork(valid_lines)
    diversions = pd.DataFrame({'from_segnum': [0, 2]})
    # check errors
    with pytest.raises(
            AttributeError,
            match=r'use \'set_diversions\(\)\' method'):
        n.diversions = diversions
    with pytest.raises(
            ValueError,
            match=r'a \[Geo\]DataFrame is expected'):
        n.set_diversions(diversions.from_segnum)
    with pytest.raises(
            ValueError,
            match='does not appear to be spatial'):
        n.set_diversions(pd.DataFrame([1]))
    # normal operation
    assert n.diversions is None
    n.set_diversions(diversions)
    assert n.diversions is not None
    assert 'dist_end' not in n.diversions.columns
    assert 'dist_line' not in n.diversions.columns
    np.testing.assert_array_equal(n.diversions['from_segnum'], [0, 2])
    np.testing.assert_array_equal(
        n.segments['diversions'], [set([0]), None, set([1])])
    assert repr(n) == dedent('''\
        <SurfaceWaterNetwork: with Z coordinates
          3 segments: [0, 1, 2]
          2 headwater: [1, 2]
          1 outlets: [0]
          2 diversions (as DataFrame): [0, 1] />''')
    if matplotlib:
        _ = n.plot()
        plt.close()
    # Unset
    n.set_diversions(None)
    assert n.diversions is None
    assert 'diversions' not in n.segments.columns
def test_outlet_series():
    # make a network with outlet on index 2
    n = swn.SurfaceWaterNetwork(wkt_to_geoseries([
        'LINESTRING Z (40 130 15, 60 100 14)',
        'LINESTRING Z (70 130 15, 60 100 14)',
        'LINESTRING Z (60 100 14, 60  80 12)',
    ]))
    # from scalar
    v = n._outlet_series(8.0)
    assert list(v.index) == [2]
    assert list(v) == [8.0]
    assert v.name is None
    v = n._outlet_series('$VAL$')
    assert list(v) == ['$VAL$']
    # from list
    v = n._outlet_series([8])
    assert list(v.index) == [2]
    assert list(v) == [8]
    assert v.name is None
    v = n._outlet_series(['$VAL_out$'])
    assert list(v.index) == [2]
    assert list(v) == ['$VAL_out$']
    assert v.name is None
    # from Series
    s = pd.Series([5.0], index=[2])
    v = n._outlet_series(s)
    assert list(v.index) == [2]
    assert list(v) == [5.0]
    assert v.name is None
    s.name = 'foo'
    v = n._outlet_series(s)
    assert v.name == 'foo'
    # now break it
    s.index -= 1
    with pytest.raises(ValueError,
                       match='index is different than for outlets'):
        n._outlet_series(s)
def test_init_reversed_lines():
    # same as the working lines, but reversed in the opposite direction
    lines = valid_lines.geometry.apply(lambda x: LineString(x.coords[::-1]))
    n = swn.SurfaceWaterNetwork(lines)
    assert len(n.warnings) == 0
    assert len(n.errors) == 2
    assert n.errors[0] == \
        'segment 0 has more than one downstream segments: [1, 2]'
    assert n.errors[1] == \
        'starting coordinate (60.0, 100.0) matches start segment: ' + \
        str(set([1]))
    assert len(n) == 3
    assert n.has_z is True
    assert list(n.segments.index) == [0, 1, 2]
    # This is all non-sense
    assert list(n.segments['to_segnum']) == [1, -1, -1]
    assert list(n.segments['cat_group']) == [1, 1, 2]
    assert list(n.segments['num_to_outlet']) == [2, 1, 1]
    np.testing.assert_allclose(
        n.segments['dist_to_outlet'], [56.05551, 36.05551, 31.622776])
    assert list(n.segments['sequence']) == [1, 3, 2]
    assert list(n.segments['stream_order']) == [1, 1, 1]
    np.testing.assert_allclose(
        n.segments['upstream_length'], [20.0, 56.05551275, 31.6227766])
    assert list(n.headwater) == [0, 2]
    assert list(n.outlets) == [1, 2]
    assert dict(n.to_segnums) == {0: 1}
    assert n.from_segnums == {1: set([0])}
    assert repr(n) == dedent('''\
        <SurfaceWaterNetwork: with Z coordinates
          3 segments: [0, 1, 2]
          2 headwater: [0, 2]
          2 outlets: [1, 2]
          no diversions />''')
    if matplotlib:
        _ = n.plot()
        plt.close()
Ejemplo n.º 20
0
def test_copy_lines_polygons(valid_n):
    n1 = valid_n
    n2 = swn.SurfaceWaterNetwork(valid_n.segments, valid_n.END_SEGNUM)
    assert n1 is not n2
Ejemplo n.º 21
0
def test_init_errors():
    with pytest.raises(ValueError, match='segments must be a GeoDataFrame'):
        swn.SurfaceWaterNetwork(object())
    with pytest.raises(ValueError, match='segments must be a GeoDataFrame'):
        swn.SurfaceWaterNetwork(valid_df)
def fluss_n():
    return swn.SurfaceWaterNetwork(fluss_gs)
def valid_n():
    return swn.SurfaceWaterNetwork(valid_lines)
Ejemplo n.º 24
0
def test_eq_lines(valid_n):
    n1 = valid_n
    n2 = swn.SurfaceWaterNetwork(valid_n.segments, valid_n.END_SEGNUM)
    assert len(n1) == len(n2) == 3
    assert n1 == n2
Ejemplo n.º 25
0
def test_ne_lines(valid_n):
    n1 = valid_n
    n2 = swn.SurfaceWaterNetwork(valid_n.segments, valid_n.END_SEGNUM)
    n2.remove(segnums=[1])
    assert len(n1) != len(n2)
    assert n1 != n2
def test_set_diversions_geodataframe():
    n = swn.SurfaceWaterNetwork(valid_lines)
    diversions = geopandas.GeoDataFrame(geometry=[
        Point(58, 97), Point(62, 97), Point(61, 89), Point(59, 89)])
    # check errors
    with pytest.raises(
            AttributeError,
            match=r'use \'set_diversions\(\)\' method'):
        n.diversions = diversions
    with pytest.raises(
            ValueError,
            match=r'a \[Geo\]DataFrame is expected'):
        n.set_diversions([1])
    with pytest.raises(
            ValueError,
            match=r'a \[Geo\]DataFrame is expected'):
        n.set_diversions(diversions.geometry)
    with pytest.raises(
            ValueError,
            match='does not appear to be spatial'):
        n.set_diversions(geopandas.GeoDataFrame([1]))
    # normal operation
    assert n.diversions is None
    n.set_diversions(diversions)
    assert n.diversions is not None
    np.testing.assert_array_almost_equal(
        n.diversions['dist_end'], [3.605551, 3.605551, 9.055385, 9.055385])
    np.testing.assert_array_almost_equal(
        n.diversions['dist_line'], [3.605551, 3.605551, 1.0, 1.0])
    np.testing.assert_array_equal(
        n.diversions['from_segnum'], [1, 2, 0, 0])
    np.testing.assert_array_equal(
        n.segments['diversions'], [set([2, 3]), set([0]), set([1])])
    # Unset
    n.set_diversions(None)
    assert n.diversions is None
    assert 'diversions' not in n.segments.columns
    # Try again with min_stream_order option
    n.set_diversions(diversions, min_stream_order=2)
    assert n.diversions is not None
    np.testing.assert_array_almost_equal(
        n.diversions['dist_end'], [17.117243, 17.117243, 9.055385, 9.055385])
    np.testing.assert_array_equal(
        n.diversions['dist_line'], [2.0, 2.0, 1.0, 1.0])
    np.testing.assert_array_equal(
        n.diversions['from_segnum'], [0, 0, 0, 0])
    np.testing.assert_array_equal(
        n.segments['diversions'], [set([0, 1, 2, 3]), None, None])
    # Try again, but use 'from_segnum' column
    diversions = geopandas.GeoDataFrame(
        {'from_segnum': [0, 2]}, geometry=[Point(55, 97), Point(68, 105)])
    n.set_diversions(diversions)
    assert n.diversions is not None
    np.testing.assert_array_almost_equal(
        n.diversions['dist_end'], [17.720045,  9.433981])
    np.testing.assert_array_almost_equal(
        n.diversions['dist_line'], [5.0, 6.008328])
    np.testing.assert_array_equal(
        n.diversions['from_segnum'], [0, 2])
    np.testing.assert_array_equal(
        n.segments['diversions'], [set([0]), None, set([1])])
    assert repr(n) == dedent('''\
        <SurfaceWaterNetwork: with Z coordinates
          3 segments: [0, 1, 2]
          2 headwater: [1, 2]
          1 outlets: [0]
          2 diversions (as GeoDataFrame): [0, 1] />''')
    if matplotlib:
        _ = n.plot()
        plt.close()
def coastal_swn(coastal_lines_gdf):
    return swn.SurfaceWaterNetwork(coastal_lines_gdf.geometry)
def test_init_geom_type():
    wkt_list = valid_lines_list[:]
    wkt_list[1] = 'MULTILINESTRING Z ((70 130 15, 60 100 14))'
    lines = wkt_to_geoseries(wkt_list)
    with pytest.raises(ValueError, match='lines must all be LineString types'):
        swn.SurfaceWaterNetwork(lines)