geotypes 0.1.0__py3-none-any.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.
- geotypes/__init__.py +43 -0
- geotypes/features.py +164 -0
- geotypes/geometry.py +1650 -0
- geotypes/rasters.py +603 -0
- geotypes-0.1.0.dist-info/METADATA +208 -0
- geotypes-0.1.0.dist-info/RECORD +9 -0
- geotypes-0.1.0.dist-info/WHEEL +5 -0
- geotypes-0.1.0.dist-info/licenses/LICENSE.txt +21 -0
- geotypes-0.1.0.dist-info/top_level.txt +1 -0
geotypes/__init__.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import warnings
|
|
2
|
+
|
|
3
|
+
# Import modules
|
|
4
|
+
from . import geometry
|
|
5
|
+
|
|
6
|
+
# Export main geometry classes for convenient access
|
|
7
|
+
from .geometry import (
|
|
8
|
+
GeoType,
|
|
9
|
+
LL,
|
|
10
|
+
XY,
|
|
11
|
+
GeoPoint,
|
|
12
|
+
GeoPath,
|
|
13
|
+
GeoPoints,
|
|
14
|
+
GeoArea,
|
|
15
|
+
LocalPath,
|
|
16
|
+
LocalPoints,
|
|
17
|
+
LocalArea,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
# Try to import optional raster/feature modules
|
|
21
|
+
try:
|
|
22
|
+
from . import rasters
|
|
23
|
+
from . import features
|
|
24
|
+
from .rasters import Raster
|
|
25
|
+
except ImportError as e:
|
|
26
|
+
warnings.warn(f"geotypes raster capability not loaded. Error: {e}")
|
|
27
|
+
|
|
28
|
+
__all__ = [
|
|
29
|
+
"geometry",
|
|
30
|
+
"rasters",
|
|
31
|
+
"features",
|
|
32
|
+
"GeoType",
|
|
33
|
+
"LL",
|
|
34
|
+
"XY",
|
|
35
|
+
"GeoPoint",
|
|
36
|
+
"GeoPath",
|
|
37
|
+
"GeoPoints",
|
|
38
|
+
"GeoArea",
|
|
39
|
+
"LocalPath",
|
|
40
|
+
"LocalPoints",
|
|
41
|
+
"LocalArea",
|
|
42
|
+
"Raster",
|
|
43
|
+
]
|
geotypes/features.py
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import warnings
|
|
3
|
+
from .geometry import LL, GeoPoint, GeoPoints, GeoPath, check_crs_equal
|
|
4
|
+
from .rasters import Raster, RasterRegistry
|
|
5
|
+
from typing import Union, Iterable, Optional
|
|
6
|
+
from multiprocessing import Pool, cpu_count
|
|
7
|
+
|
|
8
|
+
class FeatureExtractorBase:
|
|
9
|
+
def get_output_format(self):
|
|
10
|
+
"""
|
|
11
|
+
Returns the output format of the feature vector, where the length corresponds to the length of the feature vector.
|
|
12
|
+
i.e. if the feature vector contains [depth,slope,aspect,rugosity] this function would return ["depth","slope","aspect","rugosity"]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
Returns:
|
|
16
|
+
[str]: maps index to feature vector item.
|
|
17
|
+
"""
|
|
18
|
+
raise NotImplementedError()
|
|
19
|
+
|
|
20
|
+
def get_z(self, p: Union[LL, GeoPoint]):
|
|
21
|
+
"""
|
|
22
|
+
Gets the features at a given lat/lon
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
p: (LL,GeoPoint) Lat/lon or GeoPoint
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
np.ndarray: Features at the given location.
|
|
29
|
+
"""
|
|
30
|
+
raise NotImplementedError()
|
|
31
|
+
|
|
32
|
+
def get_zs(self, ps: GeoPoints) -> np.ndarray:
|
|
33
|
+
"""
|
|
34
|
+
Gets the features at a given set of lat/lon points
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
ps: (GeoPoints) The set of points
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
np.ndarray: The features at the given location.
|
|
41
|
+
"""
|
|
42
|
+
raise NotImplementedError()
|
|
43
|
+
|
|
44
|
+
def check_valid(self, samples: Union[GeoPoint, LL, GeoPoints, GeoPath]):
|
|
45
|
+
"""
|
|
46
|
+
Checks if a sample set is valid.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
samples: (GeoPoint, LL, GeoPoints, GeoPath) The samples to check.
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
bool: True if the samples are valid, False otherwise.
|
|
53
|
+
"""
|
|
54
|
+
raise NotImplementedError()
|
|
55
|
+
|
|
56
|
+
def get_named_zs(self, p: Union[LL, GeoPoint]):
|
|
57
|
+
"""
|
|
58
|
+
Gets the features at a given lat/lon
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
p: (LL,GeoPoint) Lat/lon or GeoPoint
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
dict: Features at the given location.
|
|
65
|
+
"""
|
|
66
|
+
raise NotImplementedError()
|
|
67
|
+
|
|
68
|
+
class FeaturesFromRaster:
|
|
69
|
+
"""
|
|
70
|
+
Gathers raw features from a raster.
|
|
71
|
+
"""
|
|
72
|
+
def __init__(self, raster_registry: RasterRegistry):
|
|
73
|
+
self.raster_registry = raster_registry
|
|
74
|
+
|
|
75
|
+
def get_output_format(self):
|
|
76
|
+
"""
|
|
77
|
+
Returns the output format of the feature vector, where the length corresponds to the length of the feature vector.
|
|
78
|
+
i.e. if the feature vector contains [depth,slope,aspect,rugosity] this function would return ["depth","slope","aspect","rugosity"]
|
|
79
|
+
Returns:
|
|
80
|
+
[str]: maps index to feature vector item.
|
|
81
|
+
"""
|
|
82
|
+
return list(self.raster_registry.keys())
|
|
83
|
+
|
|
84
|
+
def get_z(self, p: Union[LL, GeoPoint]):
|
|
85
|
+
"""
|
|
86
|
+
Gets the features at a given lat/lon
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
p: (LL,GeoPoint) Lat/lon or GeoPoint
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
np.ndarray: Features at the given location.
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
# Checks for either LL or GeoPoint
|
|
96
|
+
if isinstance(p, LL):
|
|
97
|
+
use_ll = True
|
|
98
|
+
elif isinstance(p, GeoPoint):
|
|
99
|
+
use_ll = False
|
|
100
|
+
else:
|
|
101
|
+
raise ValueError("p must be LL or GeoPoint")
|
|
102
|
+
|
|
103
|
+
feats = []
|
|
104
|
+
data_ok = True
|
|
105
|
+
# iterate over the rasters and get the values
|
|
106
|
+
for rname,ritem in self.raster_registry.items():
|
|
107
|
+
if use_ll:
|
|
108
|
+
v = ritem.dataset.get_value_at_ll(p, band=ritem.band) # check if the value is valid
|
|
109
|
+
else:
|
|
110
|
+
v = ritem.dataset.get_value_at_geo(p, band=ritem.band)
|
|
111
|
+
# v = ritem.dataset.get_value(p)
|
|
112
|
+
|
|
113
|
+
if v is None: # if not, then we can't use this point
|
|
114
|
+
data_ok = False
|
|
115
|
+
break
|
|
116
|
+
feats.append(v)
|
|
117
|
+
if not data_ok: # if we couldn't get the data, then return None
|
|
118
|
+
return None
|
|
119
|
+
|
|
120
|
+
feat_arr = np.array(feats)
|
|
121
|
+
# feat_arr = np.concatenate(feats, axis=-1) # concatenate the features
|
|
122
|
+
feat_arr = feat_arr.squeeze() # squeeze the features
|
|
123
|
+
return feat_arr # return the features
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def get_zs(self, ps: GeoPoints) -> np.ndarray:
|
|
127
|
+
"""
|
|
128
|
+
Gets the features at a given set of lat/lon points
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
ps: (GeoPoints) The set of points
|
|
132
|
+
|
|
133
|
+
Returns:
|
|
134
|
+
np.ndarray: The features at the given location.
|
|
135
|
+
"""
|
|
136
|
+
features = []
|
|
137
|
+
for rname, ritem in self.raster_registry.items():
|
|
138
|
+
if check_crs_equal(ritem.dataset.dataset.crs, ps.crs):
|
|
139
|
+
ps_crs = ps
|
|
140
|
+
else:
|
|
141
|
+
ps_crs = ps.to_crs(ritem.dataset.dataset.crs)
|
|
142
|
+
|
|
143
|
+
features.append(np.array(ritem.dataset.get_value(ps_crs)).squeeze())
|
|
144
|
+
|
|
145
|
+
if len(features) == 0:
|
|
146
|
+
return None
|
|
147
|
+
return np.asarray(features).T
|
|
148
|
+
|
|
149
|
+
def check_valid(self, samples: Union[GeoPoint, LL, GeoPoints, GeoPath]):
|
|
150
|
+
"""
|
|
151
|
+
Checks if a sample set is valid.
|
|
152
|
+
|
|
153
|
+
Args:
|
|
154
|
+
samples: (GeoPoint, LL, GeoPoints, GeoPath) The samples to check.
|
|
155
|
+
|
|
156
|
+
Returns:
|
|
157
|
+
bool: True if the samples are valid, False otherwise.
|
|
158
|
+
"""
|
|
159
|
+
if isinstance(samples, (GeoPoint, LL)):
|
|
160
|
+
samples = [samples]
|
|
161
|
+
for p in samples:
|
|
162
|
+
if self.get_z(p) is None:
|
|
163
|
+
return False
|
|
164
|
+
return True
|