BERATools 0.5.2__tar.gz → 0.5.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {beratools-0.5.2 → beratools-0.5.4}/PKG-INFO +13 -13
- {beratools-0.5.2 → beratools-0.5.4}/README.md +9 -10
- {beratools-0.5.2 → beratools-0.5.4}/beratools/__init__.py +2 -2
- {beratools-0.5.2 → beratools-0.5.4}/beratools/core/algo_astar.py +151 -7
- {beratools-0.5.2 → beratools-0.5.4}/beratools/core/algo_canopy_footprint_absolute.py +1 -1
- {beratools-0.5.2 → beratools-0.5.4}/beratools/core/algo_centerline.py +467 -129
- {beratools-0.5.2 → beratools-0.5.4}/beratools/core/algo_check_seed_line.py +112 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/core/algo_common.py +671 -5
- {beratools-0.5.2 → beratools-0.5.4}/beratools/core/algo_cost.py +137 -1
- {beratools-0.5.2 → beratools-0.5.4}/beratools/core/algo_geometry.py +11 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/core/algo_line_grouping.py +19 -3
- {beratools-0.5.2 → beratools-0.5.4}/beratools/core/algo_merge_lines.py +1 -1
- {beratools-0.5.2 → beratools-0.5.4}/beratools/core/algo_seed_line_correction.py +1 -1
- {beratools-0.5.2 → beratools-0.5.4}/beratools/core/algo_vertex_optimization.py +1 -1
- beratools-0.5.4/beratools/core/alt_spatial_common.py +149 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/core/constants.py +1 -1
- beratools-0.5.4/beratools/core/logger.py +376 -0
- beratools-0.5.4/beratools/core/tool_base.py +217 -0
- beratools-0.5.4/beratools/external/polygon_centerline/_src.py +2598 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/gui/assets/beratools.json +7 -7
- {beratools-0.5.2 → beratools-0.5.4}/beratools/gui/bt_data.py +2 -2
- {beratools-0.5.2 → beratools-0.5.4}/beratools/gui/bt_gui_main.py +1 -1
- {beratools-0.5.2 → beratools-0.5.4}/beratools/gui/main.py +1 -1
- {beratools-0.5.2 → beratools-0.5.4}/beratools/gui/tool_widgets.py +2 -2
- {beratools-0.5.2 → beratools-0.5.4}/beratools/tools/canopy_footprint_absolute.py +3 -4
- {beratools-0.5.2 → beratools-0.5.4}/beratools/tools/centerline.py +140 -17
- {beratools-0.5.2 → beratools-0.5.4}/beratools/tools/check_seed_line.py +11 -5
- {beratools-0.5.2 → beratools-0.5.4}/beratools/tools/common.py +1 -1
- {beratools-0.5.2 → beratools-0.5.4}/beratools/tools/ground_footprint.py +3 -5
- {beratools-0.5.2 → beratools-0.5.4}/beratools/tools/tool_template.py +1 -1
- {beratools-0.5.2 → beratools-0.5.4}/beratools/tools/vertex_optimization.py +3 -6
- {beratools-0.5.2 → beratools-0.5.4}/beratools/utility/spatial_common.py +1 -1
- {beratools-0.5.2 → beratools-0.5.4}/pyproject.toml +2 -1
- beratools-0.5.2/beratools/core/alt_spatial_common.py +0 -108
- beratools-0.5.2/beratools/core/logger.py +0 -93
- beratools-0.5.2/beratools/core/tool_base.py +0 -140
- beratools-0.5.2/beratools/external/polygon_centerline/_src.py +0 -1058
- {beratools-0.5.2 → beratools-0.5.4}/.gitignore +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/LICENSE +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/cli/__init__.py +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/cli/entry.py +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/core/__init__.py +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/core/algo_check_seed_line_validate.py +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/core/algo_dijkstra.py +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/core/algo_split_with_lines.py +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/core/algo_vertex_preclean.py +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/core/canopy_threshold_relative.py +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/core/line_footprint_functions.py +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/core/tool_geo_simplify.py +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/external/__init__.py +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/external/geo_simplify/geo-simplify-linux-x64 +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/external/geo_simplify/geo-simplify-win-x64.exe +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/external/polygon_centerline/LICENSE.md +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/external/polygon_centerline/UPSTREAM.md +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/external/polygon_centerline/__init__.py +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/external/polygon_centerline/exceptions.py +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/gui/assets/BERALogo.ico +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/gui/assets/BERALogo.png +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/gui/assets/BERA_GUI_Main.png +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/gui/assets/BERA_Splash.gif +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/gui/assets/BERA_WizardImage.png +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/gui/assets/closed.gif +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/gui/assets/closed.png +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/gui/assets/gui.json +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/gui/assets/open.gif +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/gui/assets/open.png +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/gui/assets/tool.gif +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/gui/assets/tool.png +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/gui/geometry_types.py +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/tools/__init__.py +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/tools/line_footprint_relative.py +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/utility/env_checks.py +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/utility/tool_args.py +0 -0
- {beratools-0.5.2 → beratools-0.5.4}/beratools/utility/unit_conversion.py +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: BERATools
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.4
|
|
4
4
|
Summary: An advanced forest line feature analysis platform
|
|
5
|
-
Project-URL: Homepage, https://github.com/
|
|
5
|
+
Project-URL: Homepage, https://github.com/BERATool/beratools
|
|
6
6
|
Author-email: AppliedGRG <appliedgrg@gmail.com>, Richard Zeng <richardqzeng@gmail.com>
|
|
7
7
|
License: GPL-3.0-or-later
|
|
8
8
|
License-File: LICENSE
|
|
@@ -17,6 +17,7 @@ Classifier: Programming Language :: Python :: 3.14
|
|
|
17
17
|
Requires-Python: <3.15,>=3.12
|
|
18
18
|
Requires-Dist: gdal<4,>=3.12; platform_system != 'Windows'
|
|
19
19
|
Requires-Dist: geopandas
|
|
20
|
+
Requires-Dist: igraph
|
|
20
21
|
Requires-Dist: networkit
|
|
21
22
|
Requires-Dist: numpy<2.4,>=1.26
|
|
22
23
|
Requires-Dist: pandarallel
|
|
@@ -55,8 +56,8 @@ BERA Tools is successor of [Forest Line Mapper](https://github.com/appliedgrg/fl
|
|
|
55
56
|
|
|
56
57
|
<div align="center">
|
|
57
58
|
|
|
58
|
-
[](https://github.com/BERATool/beratools/actions/workflows/python-integration-tests.yml)
|
|
60
|
+
[](https://beratool.github.io/beratools/)
|
|
60
61
|
[](https://anaconda.org/AppliedGRG/beratools)
|
|
61
62
|
[](https://pypi.org/project/BERATools/)
|
|
62
63
|
[](https://www.python.org/downloads/)
|
|
@@ -64,7 +65,7 @@ BERA Tools is successor of [Forest Line Mapper](https://github.com/appliedgrg/fl
|
|
|
64
65
|
|
|
65
66
|
</div>
|
|
66
67
|
|
|
67
|
-
## [Quick Start](https://
|
|
68
|
+
## [Quick Start](https://beratool.github.io/beratools/)
|
|
68
69
|
|
|
69
70
|
Here are the ways to install BERA Tools:
|
|
70
71
|
|
|
@@ -73,15 +74,14 @@ Here are the ways to install BERA Tools:
|
|
|
73
74
|
|
|
74
75
|
### Windows Installer
|
|
75
76
|
|
|
76
|
-
Windows installer is provided with releases. Check the [latest release](https://github.com/
|
|
77
|
+
Windows installer is provided with releases. Check the [latest release](https://github.com/BERATool/beratools/releases/latest). Official Windows installers are signed under the BERA Tools [Code signing policy](CODE_SIGNING_POLICY.md).
|
|
77
78
|
|
|
78
79
|
### Install with Anaconda
|
|
79
80
|
|
|
80
81
|
Install with Anaconda works on Windows, macOS, and Linux.
|
|
81
82
|
|
|
82
83
|
- Install Miniconda. Download Miniconda from [Miniconda](https://docs.anaconda.com/miniconda/) and install on your machine.
|
|
83
|
-
- Download and save the file [environment.yml](https://raw.githubusercontent.com/
|
|
84
|
-
).
|
|
84
|
+
- Download and save the file [environment.yml](https://raw.githubusercontent.com/BERATool/beratools/main/environment.yml).
|
|
85
85
|
- Launch **Anaconda Prompt** and **Change directory** to where environment.yml is saved.
|
|
86
86
|
- Run the command to install BERA Tools.
|
|
87
87
|
|
|
@@ -99,13 +99,13 @@ Install with Anaconda works on Windows, macOS, and Linux.
|
|
|
99
99
|
|
|
100
100
|

|
|
101
101
|
|
|
102
|
-
- [Download latest example data](https://github.com/
|
|
102
|
+
- [Download latest example data](https://github.com/BERATool/beratools/releases/latest/download/test_data.zip) to try with BERA Tools.
|
|
103
103
|
|
|
104
|
-
For more information about installation, check the [BERA Tools Installation](https://
|
|
104
|
+
For more information about installation, check the [BERA Tools Installation](https://beratool.github.io/beratools/user/installation/).
|
|
105
105
|
|
|
106
106
|
## BERA Tools Guide
|
|
107
107
|
|
|
108
|
-
Check the online [BERA Tools Guide](https://
|
|
108
|
+
Check the online [BERA Tools Guide](https://beratool.github.io/beratools/) for user, developer and technical guides.
|
|
109
109
|
|
|
110
110
|
## Sponsors
|
|
111
111
|
|
|
@@ -126,7 +126,7 @@ Check the online [BERA Tools Guide](https://appliedgrg.github.io/beratools/) for
|
|
|
126
126
|
|
|
127
127
|
<table>
|
|
128
128
|
<tr>
|
|
129
|
-
<td><img src="https://github.com/
|
|
129
|
+
<td><img src="https://github.com/BERATool/beratools/raw/main/docs/files/icons/bera_logo.png" alt="Logos" width="80"></td>
|
|
130
130
|
<td>
|
|
131
131
|
<p>
|
|
132
132
|
This tool is part of the <strong><a href="http://www.beraproject.org/">Boreal Ecosystem Recovery & Assessment (BERA)</a></strong>.
|
|
@@ -4,8 +4,8 @@ BERA Tools is successor of [Forest Line Mapper](https://github.com/appliedgrg/fl
|
|
|
4
4
|
|
|
5
5
|
<div align="center">
|
|
6
6
|
|
|
7
|
-
[](https://github.com/BERATool/beratools/actions/workflows/python-integration-tests.yml)
|
|
8
|
+
[](https://beratool.github.io/beratools/)
|
|
9
9
|
[](https://anaconda.org/AppliedGRG/beratools)
|
|
10
10
|
[](https://pypi.org/project/BERATools/)
|
|
11
11
|
[](https://www.python.org/downloads/)
|
|
@@ -13,7 +13,7 @@ BERA Tools is successor of [Forest Line Mapper](https://github.com/appliedgrg/fl
|
|
|
13
13
|
|
|
14
14
|
</div>
|
|
15
15
|
|
|
16
|
-
## [Quick Start](https://
|
|
16
|
+
## [Quick Start](https://beratool.github.io/beratools/)
|
|
17
17
|
|
|
18
18
|
Here are the ways to install BERA Tools:
|
|
19
19
|
|
|
@@ -22,15 +22,14 @@ Here are the ways to install BERA Tools:
|
|
|
22
22
|
|
|
23
23
|
### Windows Installer
|
|
24
24
|
|
|
25
|
-
Windows installer is provided with releases. Check the [latest release](https://github.com/
|
|
25
|
+
Windows installer is provided with releases. Check the [latest release](https://github.com/BERATool/beratools/releases/latest). Official Windows installers are signed under the BERA Tools [Code signing policy](CODE_SIGNING_POLICY.md).
|
|
26
26
|
|
|
27
27
|
### Install with Anaconda
|
|
28
28
|
|
|
29
29
|
Install with Anaconda works on Windows, macOS, and Linux.
|
|
30
30
|
|
|
31
31
|
- Install Miniconda. Download Miniconda from [Miniconda](https://docs.anaconda.com/miniconda/) and install on your machine.
|
|
32
|
-
- Download and save the file [environment.yml](https://raw.githubusercontent.com/
|
|
33
|
-
).
|
|
32
|
+
- Download and save the file [environment.yml](https://raw.githubusercontent.com/BERATool/beratools/main/environment.yml).
|
|
34
33
|
- Launch **Anaconda Prompt** and **Change directory** to where environment.yml is saved.
|
|
35
34
|
- Run the command to install BERA Tools.
|
|
36
35
|
|
|
@@ -48,13 +47,13 @@ Install with Anaconda works on Windows, macOS, and Linux.
|
|
|
48
47
|
|
|
49
48
|

|
|
50
49
|
|
|
51
|
-
- [Download latest example data](https://github.com/
|
|
50
|
+
- [Download latest example data](https://github.com/BERATool/beratools/releases/latest/download/test_data.zip) to try with BERA Tools.
|
|
52
51
|
|
|
53
|
-
For more information about installation, check the [BERA Tools Installation](https://
|
|
52
|
+
For more information about installation, check the [BERA Tools Installation](https://beratool.github.io/beratools/user/installation/).
|
|
54
53
|
|
|
55
54
|
## BERA Tools Guide
|
|
56
55
|
|
|
57
|
-
Check the online [BERA Tools Guide](https://
|
|
56
|
+
Check the online [BERA Tools Guide](https://beratool.github.io/beratools/) for user, developer and technical guides.
|
|
58
57
|
|
|
59
58
|
## Sponsors
|
|
60
59
|
|
|
@@ -75,7 +74,7 @@ Check the online [BERA Tools Guide](https://appliedgrg.github.io/beratools/) for
|
|
|
75
74
|
|
|
76
75
|
<table>
|
|
77
76
|
<tr>
|
|
78
|
-
<td><img src="https://github.com/
|
|
77
|
+
<td><img src="https://github.com/BERATool/beratools/raw/main/docs/files/icons/bera_logo.png" alt="Logos" width="80"></td>
|
|
79
78
|
<td>
|
|
80
79
|
<p>
|
|
81
80
|
This tool is part of the <strong><a href="http://www.beraproject.org/">Boreal Ecosystem Recovery & Assessment (BERA)</a></strong>.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
__author__ = """Applied Geospatial Research Group"""
|
|
2
2
|
__email__ = 'appliedgrg@gmail.com'
|
|
3
|
-
__version__ = '0.5.
|
|
3
|
+
__version__ = '0.5.3'
|
|
4
4
|
__license__ = "GPL-3.0-or-later"
|
|
5
5
|
__copyright__ = "Copyright (c) AppliedGRG"
|
|
6
6
|
__status__ = "Pre-Alpha"
|
|
7
|
-
__url__ = "https://github.com/
|
|
7
|
+
__url__ = "https://github.com/BERATool/beratools"
|
|
8
8
|
__all__ = ["tools", "gui"]
|
|
@@ -10,9 +10,18 @@ from typing import Iterable
|
|
|
10
10
|
|
|
11
11
|
import numpy as np
|
|
12
12
|
import rasterio
|
|
13
|
+
import logging
|
|
14
|
+
|
|
13
15
|
from rasterio.features import geometry_mask
|
|
14
16
|
from scipy import ndimage
|
|
15
17
|
from shapely.geometry import LineString
|
|
18
|
+
import shapely.ops as sh_ops
|
|
19
|
+
import shapely.geometry as sh_geom
|
|
20
|
+
import beratools.core.algo_common as algo_common
|
|
21
|
+
|
|
22
|
+
LOGGER_NAME = "centerline"
|
|
23
|
+
logger = logging.getLogger(LOGGER_NAME)
|
|
24
|
+
|
|
16
25
|
|
|
17
26
|
|
|
18
27
|
SQRT2 = math.sqrt(2.0)
|
|
@@ -39,21 +48,139 @@ class AStarAccumulation:
|
|
|
39
48
|
g_scores: np.ndarray
|
|
40
49
|
closed: np.ndarray
|
|
41
50
|
|
|
51
|
+
def nearest_valid_cell(cost, start_rc, max_radius=20):
|
|
52
|
+
"""find the nearest valid cell if lcp start/end point land on nodata cell."""
|
|
53
|
+
r0, c0 = start_rc
|
|
54
|
+
if np.isfinite(cost[r0, c0]):
|
|
55
|
+
return start_rc
|
|
56
|
+
rows, cols = cost.shape
|
|
57
|
+
for radius in range(1, max_radius + 1):
|
|
58
|
+
rmin = max(0, r0 - radius)
|
|
59
|
+
rmax = min(rows, r0 + radius + 1)
|
|
60
|
+
cmin = max(0, c0 - radius)
|
|
61
|
+
cmax = min(cols, c0 + radius + 1)
|
|
62
|
+
best_cell = None
|
|
63
|
+
best_dist = float("inf")
|
|
64
|
+
for r in range(rmin, rmax):
|
|
65
|
+
for c in range(cmin, cmax):
|
|
66
|
+
if not np.isfinite(cost[r, c]):
|
|
67
|
+
continue
|
|
68
|
+
dist = (r - r0) ** 2 + (c - c0) ** 2
|
|
69
|
+
if dist < best_dist:
|
|
70
|
+
best_dist = dist
|
|
71
|
+
best_cell = (r, c)
|
|
72
|
+
if best_cell is not None:
|
|
73
|
+
return best_cell
|
|
74
|
+
return None
|
|
42
75
|
|
|
43
|
-
def
|
|
76
|
+
def nearest_valid_location_on_line(
|
|
77
|
+
cost_arr,
|
|
78
|
+
transform,
|
|
79
|
+
line,
|
|
80
|
+
from_start=True,
|
|
81
|
+
step=1.0,
|
|
82
|
+
max_search=20.0,
|
|
83
|
+
):
|
|
84
|
+
length = line.length
|
|
85
|
+
|
|
86
|
+
if from_start:
|
|
87
|
+
distances = np.arange(0, min(max_search, length), step)
|
|
88
|
+
else:
|
|
89
|
+
distances = np.arange(
|
|
90
|
+
length,
|
|
91
|
+
max(length - max_search, 0),
|
|
92
|
+
-step,
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
for d in distances:
|
|
96
|
+
pt = line.interpolate(d)
|
|
97
|
+
|
|
98
|
+
r, c = rasterio.transform.rowcol(
|
|
99
|
+
transform,
|
|
100
|
+
pt.x,
|
|
101
|
+
pt.y,
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
if np.isfinite(cost_arr[r, c]):
|
|
105
|
+
return pt, (r, c)
|
|
106
|
+
|
|
107
|
+
return None, None
|
|
108
|
+
|
|
109
|
+
def find_least_cost_path_astar_closest_line(cost_arr, meta: dict, input_line: LineString, cid=None) -> LineString | None:
|
|
44
110
|
"""Find an 8-neighbor A* LCP, tie-broken toward the seed-line direction."""
|
|
45
111
|
|
|
46
112
|
if input_line is None or input_line.is_empty or len(input_line.coords) < 2:
|
|
113
|
+
logger.info(cid+f"Input line is empty or too short: {input_line}")
|
|
47
114
|
return None
|
|
48
115
|
|
|
116
|
+
x1, y1 = input_line.coords[0]
|
|
117
|
+
x2, y2 = input_line.coords[-1]
|
|
49
118
|
costs, walkable = _prepare_lcp_costs(cost_arr, meta.get("nodata"))
|
|
50
119
|
rows, cols = costs.shape
|
|
51
120
|
transformer = rasterio.transform.AffineTransformer(meta["transform"])
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
121
|
+
start_rc = rasterio.transform.rowcol(meta["transform"], x1, y1)
|
|
122
|
+
end_rc = rasterio.transform.rowcol(meta["transform"], x2, y2)
|
|
123
|
+
if not walkable[start_rc]:
|
|
124
|
+
start_xy_pt,start_rc_fixed=nearest_valid_location_on_line(cost_arr, meta["transform"], input_line,
|
|
125
|
+
from_start=True,step=meta["transform"].a,
|
|
126
|
+
max_search=10.0)
|
|
127
|
+
if start_rc_fixed is None:
|
|
128
|
+
start_rc_fixed = nearest_valid_cell(cost_arr, start_rc)
|
|
129
|
+
if start_rc_fixed is None:
|
|
130
|
+
logger.info(cid+f"Start point is not traversable: {start_rc}")
|
|
131
|
+
return None
|
|
132
|
+
else:
|
|
133
|
+
sx,sy=rasterio.transform.xy(meta["transform"], start_rc_fixed[0], start_rc_fixed[-1])
|
|
134
|
+
start_xy_pt =sh_geom.Point(sx,sy)
|
|
135
|
+
|
|
136
|
+
ds=input_line.project(start_xy_pt)
|
|
137
|
+
start_connector=sh_ops.substring(input_line,0,ds)
|
|
138
|
+
logger.warning(
|
|
139
|
+
cid +
|
|
140
|
+
f" start_connector_type={type(start_connector).__name__ if start_connector is not None else None}"
|
|
141
|
+
)
|
|
142
|
+
start_xy=start_xy_pt.coords[0]
|
|
143
|
+
logger.warning(
|
|
144
|
+
cid +
|
|
145
|
+
f" moved start {start_rc}->{start_rc_fixed}"
|
|
146
|
+
)
|
|
147
|
+
else:
|
|
148
|
+
start_rc_fixed = start_rc
|
|
149
|
+
start_connector=None
|
|
150
|
+
start_xy = (x1, y1)
|
|
151
|
+
if not walkable[end_rc]:
|
|
152
|
+
end_xy_pt,end_rc_fixed=nearest_valid_location_on_line(cost_arr, meta["transform"], input_line,
|
|
153
|
+
from_start=False,step=meta["transform"].a,
|
|
154
|
+
max_search=10.0)
|
|
155
|
+
if end_rc_fixed is None:
|
|
156
|
+
end_rc_fixed= nearest_valid_cell(cost_arr, end_rc)
|
|
157
|
+
if end_rc_fixed is None:
|
|
158
|
+
logger.info(cid+f"End point is not traversable: {end_rc}")
|
|
159
|
+
return None
|
|
160
|
+
else:
|
|
161
|
+
ex,ey=rasterio.transform.xy(meta["transform"], end_rc_fixed[0], end_rc_fixed[-1])
|
|
162
|
+
end_xy_pt =sh_geom.Point(ex,ey)
|
|
163
|
+
de = input_line.project(end_xy_pt)
|
|
164
|
+
end_connector = sh_ops.substring(input_line, de, input_line.length)
|
|
165
|
+
logger.warning(
|
|
166
|
+
cid +
|
|
167
|
+
f" end_connector_type={type(end_connector).__name__ if end_connector is not None else None}"
|
|
168
|
+
)
|
|
169
|
+
end_xy = end_xy_pt.coords[0]
|
|
170
|
+
logger.warning(
|
|
171
|
+
cid +
|
|
172
|
+
f" moved end {end_rc}->{end_rc_fixed}"
|
|
173
|
+
)
|
|
174
|
+
else:
|
|
175
|
+
end_rc_fixed = end_rc
|
|
176
|
+
end_xy = (x2, y2)
|
|
177
|
+
end_connector = None
|
|
178
|
+
|
|
179
|
+
start = _clamp_row_col(start_rc_fixed, rows, cols)
|
|
180
|
+
end = _clamp_row_col(end_rc_fixed, rows, cols)
|
|
56
181
|
if not walkable[start] or not walkable[end]:
|
|
182
|
+
logger.info(cid+
|
|
183
|
+
f"Start or end point is not traversable: {start_rc_fixed} or {end_rc_fixed}")
|
|
57
184
|
return None
|
|
58
185
|
|
|
59
186
|
min_cost = float(costs[walkable].min()) if np.any(walkable) else 0.0
|
|
@@ -73,7 +200,19 @@ def find_least_cost_path_astar_closest_line(cost_arr, meta: dict, input_line: Li
|
|
|
73
200
|
if current in closed:
|
|
74
201
|
continue
|
|
75
202
|
if current == end:
|
|
76
|
-
|
|
203
|
+
lcp = _path_to_linestring(_reconstruct_path(came_from, end), transformer, start_xy, end_xy)
|
|
204
|
+
segments = []
|
|
205
|
+
if start_connector is not None:
|
|
206
|
+
segments.append(start_connector)
|
|
207
|
+
|
|
208
|
+
segments.append(lcp)
|
|
209
|
+
|
|
210
|
+
if end_connector is not None:
|
|
211
|
+
segments.append(end_connector)
|
|
212
|
+
if len(segments) == 1:
|
|
213
|
+
return segments[0]
|
|
214
|
+
return algo_common._safe_linemerge(sh_geom.MultiLineString(segments))
|
|
215
|
+
|
|
77
216
|
closed.add(current)
|
|
78
217
|
|
|
79
218
|
for neighbor in _neighbors(current, rows, cols, walkable):
|
|
@@ -94,7 +233,7 @@ def find_least_cost_path_astar_closest_line(cost_arr, meta: dict, input_line: Li
|
|
|
94
233
|
heap,
|
|
95
234
|
_lcp_queue_entry(neighbor, end, start, new_g, new_tie, min_cost, next(sequence)),
|
|
96
235
|
)
|
|
97
|
-
|
|
236
|
+
logger.info(cid+f'No path found between {start_rc_fixed} and {end_rc_fixed} using A* LCP.')
|
|
98
237
|
return None
|
|
99
238
|
|
|
100
239
|
|
|
@@ -120,6 +259,11 @@ def astar_accumulation_corridor_raster(
|
|
|
120
259
|
end_xy = lc_path.coords[-1]
|
|
121
260
|
source = _clamp_row_col(transformer.rowcol(*start_xy), rows, cols)
|
|
122
261
|
destination = _clamp_row_col(transformer.rowcol(*end_xy), rows, cols)
|
|
262
|
+
if not np.isfinite(cost[source]):
|
|
263
|
+
_, source = nearest_valid_location_on_line(cost_arr, meta["transform"], lc_path, from_start=True,step=meta['transform'].a)
|
|
264
|
+
|
|
265
|
+
if not np.isfinite(cost[destination]):
|
|
266
|
+
_, destination = nearest_valid_location_on_line(cost_arr, meta["transform"], lc_path, from_start=False,step=meta['transform'].a)
|
|
123
267
|
sampling = _raster_sampling(transform)
|
|
124
268
|
|
|
125
269
|
forward = _astar_mcp_geometric_accumulation(
|
|
@@ -8,7 +8,7 @@ Author: Richard Zeng, Maverick Fong
|
|
|
8
8
|
|
|
9
9
|
Description:
|
|
10
10
|
This script is part of the BERA Tools.
|
|
11
|
-
Webpage: https://github.com/
|
|
11
|
+
Webpage: https://github.com/BERATool/beratools
|
|
12
12
|
|
|
13
13
|
The purpose of this script is to provide main interface for adaptive relative canopy footprint tool.
|
|
14
14
|
The tool is used to generate the canopy footprint of a line based on adaptive relative threshold.
|