py4dgeo 0.7.0__cp313-cp313-win_amd64.whl
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.
- _py4dgeo.cp313-win_amd64.pyd +0 -0
- py4dgeo/UpdateableZipFile.py +81 -0
- py4dgeo/__init__.py +32 -0
- py4dgeo/cloudcompare.py +32 -0
- py4dgeo/epoch.py +814 -0
- py4dgeo/fallback.py +159 -0
- py4dgeo/logger.py +77 -0
- py4dgeo/m3c2.py +244 -0
- py4dgeo/m3c2ep.py +855 -0
- py4dgeo/pbm3c2.py +3870 -0
- py4dgeo/py4dgeo_python.cpp +487 -0
- py4dgeo/registration.py +474 -0
- py4dgeo/segmentation.py +1280 -0
- py4dgeo/util.py +263 -0
- py4dgeo-0.7.0.dist-info/METADATA +200 -0
- py4dgeo-0.7.0.dist-info/RECORD +20 -0
- py4dgeo-0.7.0.dist-info/WHEEL +5 -0
- py4dgeo-0.7.0.dist-info/entry_points.txt +3 -0
- py4dgeo-0.7.0.dist-info/licenses/COPYING.md +17 -0
- py4dgeo-0.7.0.dist-info/licenses/LICENSE.md +5 -0
py4dgeo/util.py
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import collections
|
|
2
|
+
import logging
|
|
3
|
+
import numpy as np
|
|
4
|
+
import os
|
|
5
|
+
import platform
|
|
6
|
+
import pooch
|
|
7
|
+
import requests
|
|
8
|
+
import sys
|
|
9
|
+
import xdg
|
|
10
|
+
|
|
11
|
+
from importlib import metadata
|
|
12
|
+
|
|
13
|
+
import _py4dgeo
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# The current data archive URL
|
|
17
|
+
TEST_DATA_ARCHIVE = "https://github.com/3dgeo-heidelberg/py4dgeo-test-data/releases/download/2024-06-28/data.tar.gz"
|
|
18
|
+
TEST_DATA_CHECKSUM = "5ee51a43b008181b829113d8b967cdf519eae4ac37a3301f1eaf53d15d3016cc"
|
|
19
|
+
|
|
20
|
+
# Read the version from package metadata
|
|
21
|
+
__version__ = metadata.version(__package__)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class Py4DGeoError(Exception):
|
|
25
|
+
def __init__(self, msg, loggername="py4dgeo"):
|
|
26
|
+
# Initialize the base class
|
|
27
|
+
super().__init__(msg)
|
|
28
|
+
|
|
29
|
+
# Also write the message to the error stream
|
|
30
|
+
logger = logging.getLogger(loggername)
|
|
31
|
+
logger.error(self)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def download_test_data(path=pooch.os_cache("py4dgeo"), fatal=False):
|
|
35
|
+
"""Download the test data and copy it into the given path"""
|
|
36
|
+
try:
|
|
37
|
+
return pooch.retrieve(
|
|
38
|
+
TEST_DATA_ARCHIVE,
|
|
39
|
+
TEST_DATA_CHECKSUM,
|
|
40
|
+
path=path,
|
|
41
|
+
downloader=pooch.HTTPDownloader(timeout=(3, None)),
|
|
42
|
+
processor=pooch.Untar(extract_dir="."),
|
|
43
|
+
)
|
|
44
|
+
except requests.RequestException as e:
|
|
45
|
+
if fatal:
|
|
46
|
+
raise e
|
|
47
|
+
else:
|
|
48
|
+
return []
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def find_file(filename, fatal=True):
|
|
52
|
+
"""Find a file of given name on the file system.
|
|
53
|
+
|
|
54
|
+
This function is intended to use in tests and demo applications
|
|
55
|
+
to locate data files without resorting to absolute paths. You may
|
|
56
|
+
use it for your code as well.
|
|
57
|
+
|
|
58
|
+
It looks in the following locations:
|
|
59
|
+
|
|
60
|
+
* If an absolute filename is given, it is used
|
|
61
|
+
* Check whether the given relative path exists with respect to the current working directory
|
|
62
|
+
* Check whether the given relative path exists with respect to the specified XDG data directory (e.g. through the environment variable :code:`XDG_DATA_DIRS`).
|
|
63
|
+
* Check whether the given relative path exists in downloaded test data.
|
|
64
|
+
|
|
65
|
+
:param filename:
|
|
66
|
+
The (relative) filename to search for
|
|
67
|
+
:type filename: str
|
|
68
|
+
:param fatal:
|
|
69
|
+
Whether not finding the file should be a fatal error
|
|
70
|
+
:type fatal: bool
|
|
71
|
+
:return: An absolute filename
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
# If the path is absolute, do not change it
|
|
75
|
+
if os.path.isabs(filename):
|
|
76
|
+
return filename
|
|
77
|
+
|
|
78
|
+
# Gather a list of candidate paths for relative path
|
|
79
|
+
candidates = []
|
|
80
|
+
|
|
81
|
+
# Use the current working directory
|
|
82
|
+
candidates.append(os.path.join(os.getcwd(), filename))
|
|
83
|
+
|
|
84
|
+
# Use the XDG data directories
|
|
85
|
+
if platform.system() in ["Linux", "Darwin"]:
|
|
86
|
+
for xdg_dir in xdg.xdg_data_dirs():
|
|
87
|
+
candidates.append(os.path.join(xdg_dir, filename))
|
|
88
|
+
|
|
89
|
+
# Ensure that the test data is taken into account. This is properly
|
|
90
|
+
# cached across sessions and uses a connection timeout.
|
|
91
|
+
for datafile in download_test_data():
|
|
92
|
+
if os.path.basename(datafile) == filename:
|
|
93
|
+
candidates.append(datafile)
|
|
94
|
+
|
|
95
|
+
# Iterate through the list to check for file existence
|
|
96
|
+
for candidate in candidates:
|
|
97
|
+
if os.path.exists(candidate):
|
|
98
|
+
return candidate
|
|
99
|
+
|
|
100
|
+
if fatal:
|
|
101
|
+
raise FileNotFoundError(
|
|
102
|
+
f"Cannot locate file {filename}. Tried the following locations: {', '.join(candidates)}"
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
return filename
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class MemoryPolicy(_py4dgeo.MemoryPolicy):
|
|
109
|
+
"""A descriptor for py4dgeo's memory usage policy
|
|
110
|
+
|
|
111
|
+
This can be used to describe the memory usage policy that py4dgeo
|
|
112
|
+
should follow. The implementation of py4dgeo checks the currently
|
|
113
|
+
set policy whenever it would make a memory allocation of the same order
|
|
114
|
+
of magnitude as the input pointcloud or the set of corepoints.
|
|
115
|
+
To globally set the policy, use :func:`~py4dgeo.set_memory_policy`.
|
|
116
|
+
|
|
117
|
+
Currently the following policies are available:
|
|
118
|
+
|
|
119
|
+
* :code:`STRICT`: py4dgeo is not allowed to do additional memory allocations.
|
|
120
|
+
If such an allocation would be required, an error is thrown.
|
|
121
|
+
* :code:`MINIMAL`: py4dgeo is allowed to do additional memory allocations if
|
|
122
|
+
and only if they are necessary for a seemless operation of the library.
|
|
123
|
+
* :code:`COREPOINTS`: py4dgeo is allowed to do additional memory allocations
|
|
124
|
+
as part of performance trade-off considerations (e.g. precompute vs. recompute),
|
|
125
|
+
but only if the allocation is on the order of the number of corepoints.
|
|
126
|
+
This is the default behaviour of py4dgeo.
|
|
127
|
+
* :code:`RELAXED`: py4dgeo is allowed to do additional memory allocations as
|
|
128
|
+
part of performance trade-off considerations (e.g. precompute vs. recompute).
|
|
129
|
+
"""
|
|
130
|
+
|
|
131
|
+
pass
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
# The global storage for the memory policy
|
|
135
|
+
_policy = MemoryPolicy.COREPOINTS
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def set_memory_policy(policy: MemoryPolicy):
|
|
139
|
+
"""Globally set py4dgeo's memory policy
|
|
140
|
+
|
|
141
|
+
For details about the memory policy, see :class:`~py4dgeo.MemoryPolicy`.
|
|
142
|
+
Use this once before performing any operations. Changing the memory policy
|
|
143
|
+
in the middle of the computation results in undefined behaviour.
|
|
144
|
+
|
|
145
|
+
:param policy: The policy value to globally set
|
|
146
|
+
:type policy: MemoryPolicy
|
|
147
|
+
"""
|
|
148
|
+
global _policy
|
|
149
|
+
_policy = policy
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def get_memory_policy():
|
|
153
|
+
"""Access the globally set memory policy"""
|
|
154
|
+
return _policy
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def memory_policy_is_minimum(policy: MemoryPolicy):
|
|
158
|
+
"""Whether or not the globally set memory policy is at least the given one
|
|
159
|
+
|
|
160
|
+
:param policy: The policy value to compare against
|
|
161
|
+
:type policy: MemoryPolicy
|
|
162
|
+
:returns: Whether the globally set policy is at least the given one
|
|
163
|
+
:rtype: bool
|
|
164
|
+
"""
|
|
165
|
+
return policy <= get_memory_policy()
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def make_contiguous(arr: np.ndarray):
|
|
169
|
+
"""Make a numpy array contiguous
|
|
170
|
+
|
|
171
|
+
This is a no-op if the array is already contiguous and makes
|
|
172
|
+
a copy if it is not. It checks py4dgeo's memory policy before copying.
|
|
173
|
+
|
|
174
|
+
:param arr: The numpy array
|
|
175
|
+
:type arr: np.ndarray
|
|
176
|
+
"""
|
|
177
|
+
|
|
178
|
+
if arr.flags["C_CONTIGUOUS"]:
|
|
179
|
+
return arr
|
|
180
|
+
|
|
181
|
+
if not memory_policy_is_minimum(MemoryPolicy.MINIMAL):
|
|
182
|
+
raise Py4DGeoError(
|
|
183
|
+
"Using non-contiguous memory layouts requires at least the MINIMAL memory policy"
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
return np.copy(arr, order="C")
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def _as_dtype(arr, dtype, policy_check):
|
|
190
|
+
if np.issubdtype(arr.dtype, dtype):
|
|
191
|
+
return arr
|
|
192
|
+
|
|
193
|
+
if policy_check and not memory_policy_is_minimum(MemoryPolicy.MINIMAL):
|
|
194
|
+
raise Py4DGeoError(
|
|
195
|
+
f"py4dgeo expected an input of type {np.dtype(dtype).name}, but got {np.dtype(arr.dtype).name}. Current memory policy forbids automatic cast."
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
return np.asarray(arr, dtype=dtype)
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def as_double_precision(arr: np.ndarray, policy_check=True):
|
|
202
|
+
"""Ensure that a numpy array is double precision
|
|
203
|
+
|
|
204
|
+
This is a no-op if the array is already double precision and makes a copy
|
|
205
|
+
if it is not. It checks py4dgeo's memory policy before copying.
|
|
206
|
+
|
|
207
|
+
:param arr: The numpy array
|
|
208
|
+
:type arr: np.ndarray
|
|
209
|
+
"""
|
|
210
|
+
return _as_dtype(arr, np.float64, policy_check)
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def set_num_threads(num_threads: int):
|
|
214
|
+
"""Set the number of threads to use in py4dgeo
|
|
215
|
+
|
|
216
|
+
:param num_threads: The number of threads to use
|
|
217
|
+
"type num_threads: int
|
|
218
|
+
"""
|
|
219
|
+
|
|
220
|
+
try:
|
|
221
|
+
_py4dgeo.omp_set_num_threads(num_threads)
|
|
222
|
+
except AttributeError:
|
|
223
|
+
# The C++ library was built without OpenMP!
|
|
224
|
+
if num_threads != 1:
|
|
225
|
+
raise Py4DGeoError("py4dgeo was built without threading support!")
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def get_num_threads():
|
|
229
|
+
"""Get the number of threads currently used by py4dgeo
|
|
230
|
+
|
|
231
|
+
:return: The number of threads
|
|
232
|
+
:rtype: int
|
|
233
|
+
"""
|
|
234
|
+
|
|
235
|
+
try:
|
|
236
|
+
return _py4dgeo.omp_get_max_threads()
|
|
237
|
+
except AttributeError:
|
|
238
|
+
# The C++ library was built without OpenMP!
|
|
239
|
+
return 1
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def append_file_extension(filename, extension):
|
|
243
|
+
"""Append a file extension if and only if the original filename has none"""
|
|
244
|
+
|
|
245
|
+
_, ext = os.path.splitext(filename)
|
|
246
|
+
if ext == "":
|
|
247
|
+
return f"{filename}.{extension}"
|
|
248
|
+
else:
|
|
249
|
+
return filename
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def is_iterable(obj):
|
|
253
|
+
"""Whether the object is an iterable (excluding a string)"""
|
|
254
|
+
return isinstance(obj, collections.abc.Iterable) and not isinstance(obj, str)
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
def copy_test_data_entrypoint():
|
|
258
|
+
# Define the target directory
|
|
259
|
+
target = os.getcwd()
|
|
260
|
+
if len(sys.argv) > 1:
|
|
261
|
+
target = sys.argv[1]
|
|
262
|
+
|
|
263
|
+
download_test_data(path=target, fatal=True)
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: py4dgeo
|
|
3
|
+
Version: 0.7.0
|
|
4
|
+
Summary: Library for change detection in 4D point cloud data
|
|
5
|
+
Maintainer-Email: Dominic Kempf <ssc@iwr.uni-heidelberg.de>
|
|
6
|
+
License: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
7
|
+
|
|
8
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
9
|
+
|
|
10
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: C++
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering :: GIS
|
|
16
|
+
Classifier: Intended Audience :: Science/Research
|
|
17
|
+
Requires-Python: >=3.8
|
|
18
|
+
Requires-Dist: dateparser
|
|
19
|
+
Requires-Dist: laspy[lazrs]<3.0,>=2.0
|
|
20
|
+
Requires-Dist: matplotlib
|
|
21
|
+
Requires-Dist: numpy
|
|
22
|
+
Requires-Dist: pooch
|
|
23
|
+
Requires-Dist: requests
|
|
24
|
+
Requires-Dist: seaborn
|
|
25
|
+
Requires-Dist: scikit-learn
|
|
26
|
+
Requires-Dist: vedo
|
|
27
|
+
Requires-Dist: xdg
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
|
|
30
|
+
# Welcome to py4dgeo
|
|
31
|
+
|
|
32
|
+
<img src="https://github.com/3dgeo-heidelberg/py4dgeo/blob/main/py4dgeo_logo.png?raw=true" alt="logo" style="width:500px;"/>
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
[](https://opensource.org/licenses/MIT)
|
|
36
|
+
[](https://github.com/3dgeo-heidelberg/py4dgeo/actions/workflows/ci.yml)
|
|
37
|
+
[](https://pypi.org/project/py4dgeo)
|
|
38
|
+
[](https://py4dgeo.readthedocs.io/)
|
|
39
|
+
[](https://codecov.io/gh/3dgeo-heidelberg/py4dgeo)
|
|
40
|
+
|
|
41
|
+
`py4dgeo` is a `C++` library with `Python` bindings for change analysis in multitemporal and 4D point clouds.
|
|
42
|
+
|
|
43
|
+
Topographic 3D/4D point clouds are omnipresent in geosciences, environmental, ecological and archaeological sciences, robotics, and many more fields and applications. Technology to capture such data using laser scanning and photogrammetric techniques have evolved into standard tools. Dense time series of topographic point clouds are becoming increasing available and require tools for automatic analysis. Moreover, methods considering the full 4D (3D space + time) data are being developed in research and need to be made available in an accessible way with flexible integration into existent workflows.
|
|
44
|
+
|
|
45
|
+
The **main objective** of `py4dgeo` is to bundle and provide different methods of 3D/4D change analysis in a dedicated, comprehensive Python library.
|
|
46
|
+
`py4dgeo` is designed as an international open source project that can be integrated into almost any 3D and GIS software in the geodata domain supporting Python, e.g. as plugins.
|
|
47
|
+
|
|
48
|
+
`py4dgeo` is under *ongoing active development*.
|
|
49
|
+
Below, you find a list of [provided methods](#methods-provided-by-py4dgeo).
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
## 🔨 Methods provided by py4dgeo
|
|
53
|
+
|
|
54
|
+
* **M3C2 algorithm** ([Lague et al., 2013](#-literature)) for bitemporal point cloud distance computation.
|
|
55
|
+
|
|
56
|
+
* **M3C2-EP** (M3C2-EP; [Winiwarter et al., 2021](#-literature)) for statistical signal-noise separation in change analysis through error propagation.
|
|
57
|
+
|
|
58
|
+
* **4D objects-by-change** (4D-OBC; [Anders et al., 2021](#-literature)) for time series-based extraction of surface activities.
|
|
59
|
+
|
|
60
|
+
* **Correspondence-driven plane-based M3C2** ([Zahs et al., 2022](#-literature)) for lower uncertainty in 3D topographic change quantification *[under active development]*.
|
|
61
|
+
|
|
62
|
+
* **Point cloud registration using standard ICP** by calculating and applying affine transformations to point clouds using a standard ICP implementations.
|
|
63
|
+
|
|
64
|
+
* **Point cloud registration with automatic determination of stable areas** ([Yang et al., 2022](https://doi.org/10.1515/jag-2022-0031)) for multitemporal change detection.
|
|
65
|
+
|
|
66
|
+
## 🎮 Examples
|
|
67
|
+
|
|
68
|
+
### Demo notebooks using methods provided by py4dgeo
|
|
69
|
+
| | |
|
|
70
|
+
|--------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
71
|
+
| [](https://nbviewer.org/github/3dgeo-heidelberg/py4dgeo/blob/main/demo/m3c2-change_analysis.ipynb) | [](https://nbviewer.org/github/3dgeo-heidelberg/py4dgeo/blob/main/demo/m3c2ep_change_analysis.ipynb) |
|
|
72
|
+
| [](https://nbviewer.org/github/3dgeo-heidelberg/py4dgeo/blob/main/demo/4dobc-change_analysis.ipynb) | [](https://nbviewer.org/github/3dgeo-heidelberg/py4dgeo/blob/main/demo/kmeans_clustering_of_time_series.ipynb) |
|
|
73
|
+
| [](https://nbviewer.org/github/3dgeo-heidelberg/py4dgeo/blob/main/demo/principal_component_analysis_of_time_series.ipynb) | [](https://nbviewer.org/github/3dgeo-heidelberg/py4dgeo/blob/main/jupyter/pbm3c2.ipynb) |
|
|
74
|
+
[](https://nbviewer.org/github/3dgeo-heidelberg/py4dgeo/blob/main/demo/registration_standard_ICP.ipynb) |
|
|
75
|
+
|
|
76
|
+
## 💻 Installation
|
|
77
|
+
|
|
78
|
+
### Prerequisites
|
|
79
|
+
|
|
80
|
+
Using py4dgeo requires the following software installed:
|
|
81
|
+
|
|
82
|
+
* 64-bit Python `>= 3.9` (32-bit installations might cause trouble during installation of dependencies)
|
|
83
|
+
|
|
84
|
+
In order to build the package from source, the following tools are also needed.
|
|
85
|
+
|
|
86
|
+
* A C++17-compliant compiler
|
|
87
|
+
* CMake `>= 3.9`
|
|
88
|
+
* Doxygen (optional, documentation building is skipped if missing)
|
|
89
|
+
|
|
90
|
+
### Installing py4dgeo
|
|
91
|
+
|
|
92
|
+
The preferred way of installing `py4dgeo` is using `pip`.
|
|
93
|
+
|
|
94
|
+
### Installing the release version using pip
|
|
95
|
+
|
|
96
|
+
`py4dgeo` can be installed using `pip` to obtain the [current release](https://pypi.org/project/py4dgeo/):
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
python -m pip install py4dgeo
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Building from source using pip
|
|
103
|
+
|
|
104
|
+
The following sequence of commands is used to build `py4dgeo` from source:
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
git clone --recursive https://github.com/3dgeo-heidelberg/py4dgeo.git
|
|
108
|
+
cd py4dgeo
|
|
109
|
+
python -m pip install -v --editable .
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
The `--editable` flag allows you to change the Python sources of `py4dgeo` without
|
|
113
|
+
reinstalling the package. The `-v` flag enables verbose output which gives you
|
|
114
|
+
detailed information about the compilation process that you should include into
|
|
115
|
+
potential bug reports. To recompile the C++ source, please run `pip install` again.
|
|
116
|
+
In order to enable multi-threading on builds from source, your compiler toolchain
|
|
117
|
+
needs to support `OpenMP`.
|
|
118
|
+
|
|
119
|
+
If you want to contribute to the library's development you should also install
|
|
120
|
+
its additional Python dependencies for testing and documentation building:
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
python -m pip install -r requirements-dev.txt
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Setting up py4dgeo using Docker
|
|
127
|
+
|
|
128
|
+
Additionally, `py4dgeo` provides a Docker image that allows to explore
|
|
129
|
+
the library using JupyterLab. The image can be locally built and run with
|
|
130
|
+
the following commands:
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
docker build -t py4dgeo:latest .
|
|
134
|
+
docker run -t -p 8888:8888 py4dgeo:latest
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## 🐍 Documentation of software usage
|
|
138
|
+
|
|
139
|
+
As a starting point, please have a look to the [Jupyter Notebooks](jupyter) available in the repository and find the `py4dgeo` documentation [on readthedocs](https://py4dgeo.readthedocs.io/en/latest/intro.html).
|
|
140
|
+
|
|
141
|
+
## 🌐 Published test data
|
|
142
|
+
|
|
143
|
+
<!-- TODO: integrate example notebooks for these use cases and data -->
|
|
144
|
+
|
|
145
|
+
If you are looking for data to test different methods, consider the following open data publications:
|
|
146
|
+
|
|
147
|
+
### Hourly TLS point clouds of a sandy beach
|
|
148
|
+
|
|
149
|
+
<a href="https://doi.org/10.1038/s41597-022-01291-9" target="_blank"><img src="https://github.com/3dgeo-heidelberg/py4dgeo/blob/main/doc/img/data_vos_2022_kijkduin.png?raw=true" alt="" width="450" /></a>
|
|
150
|
+
<br>
|
|
151
|
+
Vos et al. (2022): [https://doi.org/10.1038/s41597-022-01291-9](https://doi.org/10.1038/s41597-022-01291-9).
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
### By-weekly TLS point clouds of an Alpine rock glacier
|
|
155
|
+
|
|
156
|
+
<a href="https://doi.org/10.11588/data/TGSVUI" target="_blank"><img src="https://github.com/3dgeo-heidelberg/py4dgeo/blob/main/doc/img/data_zahs_2022_ahk_2019_tls.png?raw=true" alt="" width="450" /></a>
|
|
157
|
+
<br>
|
|
158
|
+
Zahs et al. (2022): [https://doi.org/10.11588/data/TGSVUI](https://doi.org/10.11588/data/TGSVUI).
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
## 📑 Citation
|
|
164
|
+
Please cite py4dgeo when using it in your research and reference the appropriate release version.
|
|
165
|
+
|
|
166
|
+
<!-- TODO: All releases of py4dgeo are listed on Zenodo where you will find the citation information including DOI. -->
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
article{py4dgeo,
|
|
170
|
+
author = {py4dgeo Development Core Team}
|
|
171
|
+
title = {py4dgeo: library for change analysis in 4D point clouds},
|
|
172
|
+
journal = {},
|
|
173
|
+
year = {2022},
|
|
174
|
+
number = {},
|
|
175
|
+
volume = {},
|
|
176
|
+
doi = {},
|
|
177
|
+
url = {https://github.com/3dgeo-heidelberg/py4dgeo},
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## 💟 Funding / Acknowledgements
|
|
182
|
+
The initial software development was supported by the [**Scientific Software Center (SSC)**](https://ssc.iwr.uni-heidelberg.de/) in the Open Call 2021. The scientific software project is further supported by the research projects [**CharAct4D**](https://www.uni-heidelberg.de/charact4d) and [**AImon5.0**](https://www.uni-heidelberg.de/aimon).
|
|
183
|
+
|
|
184
|
+
## 🔔 Contact / Bugs / Feature Requests
|
|
185
|
+
|
|
186
|
+
You think you have found a bug or have specific request for a new feature? Please open a new issue in the online code repository on Github. Also for general questions please use the issue system.
|
|
187
|
+
|
|
188
|
+
Scientific requests can be directed to the [3DGeo Research Group Heidelberg](https://uni-heidelberg.de/3dgeo) and its respective members.
|
|
189
|
+
|
|
190
|
+
## 📜 License
|
|
191
|
+
|
|
192
|
+
See [LICENSE.md](LICENSE.md).
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
## 📚 Literature
|
|
196
|
+
|
|
197
|
+
* Anders, K., Winiwarter, L., Mara, H., Lindenbergh, R., Vos, S.E. & Höfle, B. (2021): Fully automatic spatiotemporal segmentation of 3D LiDAR time series for the extraction of natural surface changes. ISPRS Journal of Photogrammetry and Remote Sensing, 173, pp. 297-308. DOI: [10.1016/j.isprsjprs.2021.01.015](https://doi.org/10.1016/j.isprsjprs.2021.01.015).
|
|
198
|
+
* Lague, D., Brodu, N., & Leroux, J. (2013). Accurate 3D comparison of complex topography with terrestrial laser scanner: Application to the Rangitikei canyon (N-Z). ISPRS Journal of Photogrammetry and Remote Sensing, 82, pp. 10-26. DOI: [10.1016/j.isprsjprs.2013.04.009](https://doi.org/10.1016/j.isprsjprs.2013.04.009).
|
|
199
|
+
* Winiwarter, L., Anders, K., Höfle, B. (2021): M3C2-EP: Pushing the limits of 3D topographic point cloud change detection by error propagation. ISPRS Journal of Photogrammetry and Remote Sensing, 178, pp. 240–258. DOI: [10.1016/j.isprsjprs.2021.06.011](https://doi.org/10.1016/j.isprsjprs.2021.06.011).
|
|
200
|
+
* Zahs, V., Winiwarter, L., Anders, K., Williams, J.G., Rutzinger, M. & Höfle, B. (2022): Correspondence-driven plane-based M3C2 for lower uncertainty in 3D topographic change quantification. ISPRS Journal of Photogrammetry and Remote Sensing, 183, pp. 541-559. DOI: [10.1016/j.isprsjprs.2021.11.018](https://doi.org/10.1016/j.isprsjprs.2021.11.018).
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
_py4dgeo.cp313-win_amd64.pyd,sha256=YDayW686h0SRjOb4Na2wGiWXZ-JEDxj3uRShZ3looeE,564736
|
|
2
|
+
py4dgeo/__init__.py,sha256=T_hK47cJOktmTxJrC03Ou-JGcdhs0IEKBcPXjUT4wJ8,767
|
|
3
|
+
py4dgeo/cloudcompare.py,sha256=hCe0YKZit8XVe98DsMKeUp-m-F2-avwicgS-IRjL4EQ,1111
|
|
4
|
+
py4dgeo/epoch.py,sha256=8Q9NTxb4OoiJx4IGESDXaDe4uwcgksofiMQLChsnndI,29914
|
|
5
|
+
py4dgeo/fallback.py,sha256=dZltN-wUSMq5GYnUgCz157fh_H5gNf2MF2SdcntDQmI,5233
|
|
6
|
+
py4dgeo/logger.py,sha256=5J7DenNkvq5GMOF_Vd2kHLHGP7os1u4EFBMbyGCAJJY,2314
|
|
7
|
+
py4dgeo/m3c2.py,sha256=I-T2rnsHgZtjOcN0ONmB0UB3TlaW5je4-S0lgxhNvjo,8475
|
|
8
|
+
py4dgeo/m3c2ep.py,sha256=vqudKR_QcV7z9bYMbGssVyJ2d4q5shgFhRue_WErJQ0,29150
|
|
9
|
+
py4dgeo/pbm3c2.py,sha256=Ia7yWym0M72NNz1L-N5WhDA_ZGA_YmWmee80Dvdjgqo,146200
|
|
10
|
+
py4dgeo/py4dgeo_python.cpp,sha256=J_csxFp1FF7nWHh8_z_BTJQRKbG4oPyRrrccJjoW4zw,18960
|
|
11
|
+
py4dgeo/registration.py,sha256=aUdEas772buy31PVv-hA5Y3v-jGnnGeJB8Bo56eV4zg,17640
|
|
12
|
+
py4dgeo/segmentation.py,sha256=pzSHuWyfHfiTDpmfy2onL3XTE_9dvLz7faVr0ddV0JI,53556
|
|
13
|
+
py4dgeo/UpdateableZipFile.py,sha256=aZVdQgAc_M-EWFDIEVukgrYQUtEb5fRoRMCVxZqpggc,2770
|
|
14
|
+
py4dgeo/util.py,sha256=dB27r6UAX1V4zy-bj-TbNxtjtwebvU7T1BCd3EIj59k,8553
|
|
15
|
+
py4dgeo-0.7.0.dist-info/METADATA,sha256=jhvHo83amSpEvxj_2hXuIsBJWb1ef_ni04l70Xn9I9Q,12290
|
|
16
|
+
py4dgeo-0.7.0.dist-info/WHEEL,sha256=EIu1Wj122E8B0k-vZcnNpwplI01di2dp-9WoG1ZyqT0,106
|
|
17
|
+
py4dgeo-0.7.0.dist-info/entry_points.txt,sha256=S8EHFVRD4deFJ_N6ZWst9v_ukH5lGnZY-f8NHjYoIfk,83
|
|
18
|
+
py4dgeo-0.7.0.dist-info/licenses/COPYING.md,sha256=ZetvO_BrdyO2DkROtlUcvpd6rl1M8Ak69vyDyePCZN0,1330
|
|
19
|
+
py4dgeo-0.7.0.dist-info/licenses/LICENSE.md,sha256=Rza103klOvpFdEr8ed20dZErIT6Tm998uX2ai29wDl8,1028
|
|
20
|
+
py4dgeo-0.7.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
This is the list of copyright holders of py4dgeo.
|
|
2
|
+
|
|
3
|
+
For information on the license, see LICENSE.md.
|
|
4
|
+
|
|
5
|
+
* Dominic Kempf, 2020-2021
|
|
6
|
+
|
|
7
|
+
The file `src/py4dgeo/zipfile.py` is licensed under Python Software Foundation License Version 2.
|
|
8
|
+
Copyright (c) 2001-2022 Python Software Foundation; All Rights Reserved
|
|
9
|
+
|
|
10
|
+
The file includes a change suggested for inclusion in CPython that adds a `remove` method to
|
|
11
|
+
`zipfile.ZipFile` that allows deletion of files from archives opened in `append` mode.
|
|
12
|
+
The original suggestion is found here: https://github.com/python/cpython/pull/19358 The
|
|
13
|
+
original author, Yudi Levi, has agreed to distribution under the PSF license.
|
|
14
|
+
|
|
15
|
+
The following data files included in the repository for testing purposes are under a different license and copyright:
|
|
16
|
+
|
|
17
|
+
* `tests/data/ahk_2017_small.xyz` under CC-BY-SA 4.0. Citation: Pfeiffer, Jan; Höfle, Bernhard; Hämmerle, Martin; Zahs, Vivien; Rutzinger, Martin; Scaioni, Marco; Lindenbergh, Roderik; Oude Elberink, Sander; Pirotti, Francesco; Bremer, Magnus; Wujanz, Daniel; Zieher, Thomas (2019): Terrestrial laser scanning data of the Äußeres Hochebenkar rock glacier close to Obergurgl, Austria acquired during the Innsbruck Summer School of Alpine Research. Institute of Geography, University of Innsbruck, PANGAEA, https://doi.org/10.1594/PANGAEA.902042
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
2
|
+
|
|
3
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
4
|
+
|
|
5
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|