flkit 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.
Files changed (60) hide show
  1. flkit/__init__.py +2 -0
  2. flkit/alg/__init__.py +68 -0
  3. flkit/alg/build_idx.py +9 -0
  4. flkit/alg/c_track.py +88 -0
  5. flkit/alg/collierydb.py +1217 -0
  6. flkit/alg/del2.py +421 -0
  7. flkit/alg/delaunay_triangulation.py +476 -0
  8. flkit/alg/finite_plane_distance.py +239 -0
  9. flkit/alg/get_up_low.py +32 -0
  10. flkit/alg/in_tin.py +139 -0
  11. flkit/alg/index.py +9 -0
  12. flkit/alg/inter/BasePredictor.py +69 -0
  13. flkit/alg/inter/Kriging.py +226 -0
  14. flkit/alg/inter/KrigingM.py +262 -0
  15. flkit/alg/inter/LossFuncs.py +164 -0
  16. flkit/alg/inter/__init__.py +178 -0
  17. flkit/alg/inter/idw.py +253 -0
  18. flkit/alg/inter/midw.py +145 -0
  19. flkit/alg/inter/nearest_neighbor.py +445 -0
  20. flkit/alg/inter/rbf.py +345 -0
  21. flkit/alg/inter/trilinear.py +572 -0
  22. flkit/alg/point_in_polygon.py +126 -0
  23. flkit/alg/point_in_volume.py +188 -0
  24. flkit/alg/point_in_volume_rs.pyi +7 -0
  25. flkit/alg/point_to_triangle.py +116 -0
  26. flkit/alg/point_to_triangle_mesh.py +309 -0
  27. flkit/alg/point_to_triangle_rs.pyi +9 -0
  28. flkit/alg/rotated_rect.py +184 -0
  29. flkit/db/__init__.py +17 -0
  30. flkit/db/db_model.py +724 -0
  31. flkit/db/duck_model.py +151 -0
  32. flkit/db/fileobj.py +72 -0
  33. flkit/db/path_utl.py +174 -0
  34. flkit/mtcli/__init__.py +18 -0
  35. flkit/mtcli/core.py +489 -0
  36. flkit/mtcli/parse.py +218 -0
  37. flkit/py.typed +0 -0
  38. flkit/tools/__init__.py +28 -0
  39. flkit/tools/del_key.py +13 -0
  40. flkit/tools/dict_to_list.py +10 -0
  41. flkit/tools/get_region.py +42 -0
  42. flkit/tools/max_key.py +7 -0
  43. flkit/tools/mongo.py +119 -0
  44. flkit/tools/mt_dash.py +121 -0
  45. flkit/tools/prase_type.py +27 -0
  46. flkit/typr/Res.py +21 -0
  47. flkit/typr/__init__.py +107 -0
  48. flkit/typr/c_grid.py +425 -0
  49. flkit/typr/console.py +283 -0
  50. flkit/typr/engine.py +59 -0
  51. flkit/typr/getenv.py +89 -0
  52. flkit/typr/result.py +81 -0
  53. flkit/typr/table.py +34 -0
  54. flkit/typr/utils.py +542 -0
  55. flkit/typr/verify.py +64 -0
  56. flkit/typr/webview.py +219 -0
  57. flkit/typr/wstask.py +344 -0
  58. flkit-0.1.0.dist-info/METADATA +186 -0
  59. flkit-0.1.0.dist-info/RECORD +60 -0
  60. flkit-0.1.0.dist-info/WHEEL +4 -0
flkit/alg/inter/idw.py ADDED
@@ -0,0 +1,253 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ 反距离权重插值算法实现
5
+ Inverse Distance Weighting (IDW) Interpolation
6
+
7
+ IDW是一种基于距离的插值方法,距离越近的点权重越大。
8
+ 适用于地理空间数据插值,计算简单高效。
9
+ """
10
+
11
+ import numpy as np
12
+ from scipy.spatial import cKDTree
13
+
14
+
15
+ class IDW2D:
16
+ """
17
+ 二维反距离加权插值
18
+
19
+ 适用于地形高程插值、温度分布等二维空间数据插值
20
+ """
21
+
22
+ def __init__(self, p: float = 2.0, k: int = 12, eps: float = 1e-8):
23
+ """
24
+ 初始化IDW2D插值器
25
+
26
+ Parameters:
27
+ -----------
28
+ p : float, default=2.0
29
+ 距离权重指数,值越大距离影响越强
30
+ k : int, default=12
31
+ 使用的最近邻点数量
32
+ eps : float, default=1e-8
33
+ 数值稳定性参数
34
+ """
35
+ self.p = p
36
+ self.k = k
37
+ self.eps = eps
38
+ self.tree = None
39
+ self.known_z = None
40
+
41
+ def fit(self, xyzv: np.ndarray):
42
+ """
43
+ 训练IDW模型
44
+
45
+ Parameters:
46
+ -----------
47
+ xyzv : np.ndarray, shape (N, 3)
48
+ 已知点数据,每行为 [x, y, z],其中z为插值目标值
49
+
50
+ Returns:
51
+ --------
52
+ self : IDW2D
53
+ 返回自身以支持链式调用
54
+ """
55
+ xyzv = np.atleast_2d(xyzv)
56
+ if xyzv.shape[1] != 3:
57
+ raise ValueError("输入数据必须是3列:[x, y, z]")
58
+
59
+ self.tree = cKDTree(xyzv[:, :2])
60
+ self.known_z = xyzv[:, 2]
61
+ return self
62
+
63
+ def predict(self, xy: np.ndarray):
64
+ """
65
+ 在指定位置进行插值预测
66
+
67
+ Parameters:
68
+ -----------
69
+ xy : np.ndarray, shape (M, 2) or (2,)
70
+ 待插值点的坐标 [x, y]
71
+
72
+ Returns:
73
+ --------
74
+ float or np.ndarray
75
+ - 单点输入 (2,): 返回标量值
76
+ - 多点输入 (M, 2): 返回数组 shape (M,)
77
+ """
78
+ if self.tree is None:
79
+ raise ValueError("模型尚未训练,请先调用 fit() 方法")
80
+
81
+ # 检查输入是单点还是多点
82
+ is_single_point = xy.ndim == 1 or (xy.ndim == 2 and xy.shape[0] == 1)
83
+
84
+ xy = np.atleast_2d(xy)
85
+ if xy.shape[1] != 2:
86
+ raise ValueError("预测点坐标必须是2列:[x, y]")
87
+
88
+ # 查找最近邻点
89
+ dist, idx = self.tree.query(xy, k=min(self.k, len(self.known_z)), eps=self.eps)
90
+
91
+ # 处理单点查询的情况
92
+ if dist.ndim == 1:
93
+ dist = dist.reshape(1, -1)
94
+ idx = idx.reshape(1, -1)
95
+
96
+ # 避免除零错误
97
+ dist = np.maximum(dist, self.eps)
98
+
99
+ # 计算权重
100
+ w = 1.0 / (dist**self.p)
101
+
102
+ # 加权平均
103
+ z = np.sum(w * self.known_z[idx], axis=1) / np.sum(w, axis=1)
104
+
105
+ # 根据输入类型返回相应格式
106
+ if is_single_point:
107
+ return float(z[0]) # 单点返回标量
108
+ else:
109
+ return z # 多点返回数组
110
+
111
+
112
+ class IDW3D:
113
+ """
114
+ 三维反距离加权插值
115
+
116
+ 适用于三维空间中的属性插值,如地质属性、污染物浓度等
117
+ """
118
+
119
+ def __init__(self, p: float = 2.0, k: int = 15, eps: float = 1e-8):
120
+ """
121
+ 初始化IDW3D插值器
122
+
123
+ Parameters:
124
+ -----------
125
+ p : float, default=2.0
126
+ 距离权重指数
127
+ k : int, default=15
128
+ 使用的最近邻点数量
129
+ eps : float, default=1e-8
130
+ 数值稳定性参数
131
+ """
132
+ self.p = p
133
+ self.k = k
134
+ self.eps = eps
135
+ self.tree = None
136
+ self.known_v = None
137
+
138
+ def fit(self, xyzv: np.ndarray):
139
+ """
140
+ 训练IDW3D模型
141
+
142
+ Parameters:
143
+ -----------
144
+ xyzv : np.ndarray, shape (N, 4)
145
+ 已知点数据,每行为 [x, y, z, value]
146
+
147
+ Returns:
148
+ --------
149
+ self : IDW3D
150
+ 返回自身以支持链式调用
151
+ """
152
+ xyzv = np.atleast_2d(xyzv)
153
+ if xyzv.shape[1] != 4:
154
+ raise ValueError("输入数据必须是4列:[x, y, z, value]")
155
+
156
+ self.tree = cKDTree(xyzv[:, :3])
157
+ self.known_v = xyzv[:, 3]
158
+ return self
159
+
160
+ def predict(self, xyz: np.ndarray):
161
+ """
162
+ 在指定位置进行插值预测
163
+
164
+ Parameters:
165
+ -----------
166
+ xyz : np.ndarray, shape (M, 3) or (3,)
167
+ 待插值点的坐标 [x, y, z]
168
+
169
+ Returns:
170
+ --------
171
+ float or np.ndarray
172
+ - 单点输入 (3,): 返回标量值
173
+ - 多点输入 (M, 3): 返回数组 shape (M,)
174
+ """
175
+ if self.tree is None:
176
+ raise ValueError("模型尚未训练,请先调用 fit() 方法")
177
+
178
+ # 检查输入是单点还是多点
179
+ is_single_point = xyz.ndim == 1 or (xyz.ndim == 2 and xyz.shape[0] == 1)
180
+
181
+ xyz = np.atleast_2d(xyz)
182
+ if xyz.shape[1] != 3:
183
+ raise ValueError("预测点坐标必须是3列:[x, y, z]")
184
+
185
+ # 查找最近邻点
186
+ dist, idx = self.tree.query(xyz, k=min(self.k, len(self.known_v)), eps=self.eps)
187
+
188
+ # 处理单点查询的情况
189
+ if dist.ndim == 1:
190
+ dist = dist.reshape(1, -1)
191
+ idx = idx.reshape(1, -1)
192
+
193
+ # 避免除零错误
194
+ dist = np.maximum(dist, self.eps)
195
+
196
+ # 计算权重
197
+ w = 1.0 / (dist**self.p)
198
+
199
+ # 加权平均
200
+ v = np.sum(w * self.known_v[idx], axis=1) / np.sum(w, axis=1)
201
+
202
+ # 根据输入类型返回相应格式
203
+ if is_single_point:
204
+ return float(v[0]) # 单点返回标量
205
+ else:
206
+ return v # 多点返回数组
207
+
208
+ def predict_grid(self, x_range, y_range, z_range, resolution=None):
209
+ """
210
+ 在规则网格上进行预测
211
+
212
+ Parameters:
213
+ -----------
214
+ x_range : tuple
215
+ x方向的范围 (x_min, x_max)
216
+ y_range : tuple
217
+ y方向的范围 (y_min, y_max)
218
+ z_range : tuple
219
+ z方向的范围 (z_min, z_max)
220
+ resolution : tuple, optional
221
+ 网格分辨率 (nx, ny, nz),默认为 (50, 50, 50)
222
+
223
+ Returns:
224
+ --------
225
+ tuple
226
+ (grid_x, grid_y, grid_z, predictions)
227
+ - grid_x, grid_y, grid_z: 网格坐标
228
+ - predictions: 预测值网格
229
+ """
230
+ if self.tree is None:
231
+ raise ValueError("模型尚未训练,请先调用 fit() 方法")
232
+
233
+ if resolution is None:
234
+ resolution = (50, 50, 50)
235
+
236
+ # 创建网格
237
+ x = np.linspace(x_range[0], x_range[1], resolution[0])
238
+ y = np.linspace(y_range[0], y_range[1], resolution[1])
239
+ z = np.linspace(z_range[0], z_range[1], resolution[2])
240
+
241
+ grid_x, grid_y, grid_z = np.meshgrid(x, y, z, indexing="ij")
242
+
243
+ # 展平网格点进行预测
244
+ points = np.column_stack([grid_x.ravel(), grid_y.ravel(), grid_z.ravel()])
245
+
246
+ predictions = self.predict(points)
247
+ predictions = predictions.reshape(grid_x.shape)
248
+
249
+ return grid_x, grid_y, grid_z, predictions
250
+
251
+
252
+ # 向下兼容旧接口
253
+ IDW = IDW2D
@@ -0,0 +1,145 @@
1
+ import numpy as np
2
+ from .BasePredictor import Predictor
3
+ from .LossFuncs import ErrorMetrics
4
+
5
+
6
+ class IDW(Predictor):
7
+ class IDWModel:
8
+ def __init__(self, x, y, value, power=2):
9
+ self.x = x
10
+ self.y = y
11
+ self.value = value
12
+ self.power = power
13
+
14
+ def execute(self, point_x, point_y):
15
+ numerator = 0
16
+ denominator = 0
17
+
18
+ for i, (x, y, val) in enumerate(zip(self.x, self.y, self.value)):
19
+ d = ((x - point_x) ** 2 + (y - point_y) ** 2) ** 0.5
20
+ if d == 0:
21
+ return val, 0
22
+ weight = 1 / (d**self.power)
23
+ numerator += weight * val
24
+ denominator += weight
25
+
26
+ result = numerator / denominator
27
+ return result, 0
28
+
29
+ def fit(self, data: np.ndarray):
30
+ x = data[:, 0]
31
+ y = data[:, 1]
32
+ z = data[:, 2]
33
+ self.model = self.IDWModel(x, y, z)
34
+
35
+ def predict(self, points: np.ndarray):
36
+ z1 = np.zeros(points.shape[0])
37
+ for i in range(points.shape[0]):
38
+ z1[i], _ = self.model.execute(points[i, 0], points[i, 1])
39
+ return z1
40
+
41
+ def loss(self, data, res):
42
+ return ErrorMetrics.mse(data, res)
43
+
44
+
45
+ class IDWOpm(Predictor):
46
+ class IDWModel:
47
+ def __init__(self, x, y, value, power=2):
48
+ self.x = x
49
+ self.y = y
50
+ self.value = value
51
+ self.power = power
52
+
53
+ def execute(self, point_x, point_y):
54
+ numerator = 0
55
+ denominator = 0
56
+
57
+ for i, (x, y, val) in enumerate(zip(self.x, self.y, self.value)):
58
+ d = ((x - point_x) ** 2 + (y - point_y) ** 2) ** 0.5
59
+ if d == 0:
60
+ return val, 0
61
+ weight = 1 / (d**self.power)
62
+ numerator += weight * val
63
+ denominator += weight
64
+
65
+ result = numerator / denominator
66
+ return result, 0
67
+
68
+ def fit(self, data):
69
+ arr = np.asarray(data)
70
+ if arr.ndim != 2 or arr.shape[1] != 3:
71
+ raise ValueError("输入数据必须是3列:[x, y, z]")
72
+ x, y, z = arr[:, 0], arr[:, 1], arr[:, 2]
73
+ self.model = self.IDWModel(x.tolist(), y.tolist(), z.tolist())
74
+ return self
75
+
76
+ def predict(self, points):
77
+ arr = np.asarray(points)
78
+ if arr.ndim == 1:
79
+ x, y = float(arr[0]), float(arr[1])
80
+ result, _ = self.model.execute(x, y)
81
+ return result
82
+ elif arr.ndim == 2 and arr.shape[1] == 2:
83
+ z1 = np.zeros(arr.shape[0], dtype=float)
84
+ for i in range(arr.shape[0]):
85
+ z1[i], _ = self.model.execute(float(arr[i, 0]), float(arr[i, 1]))
86
+ return z1
87
+ else:
88
+ raise ValueError("预测点坐标必须是2列:[x, y] 或形状 (M, 2)")
89
+
90
+ def loss(self, data, res):
91
+ return ErrorMetrics.mse(data, res)
92
+
93
+
94
+ class IDWOpm3D(Predictor):
95
+ class IDWModel:
96
+ def __init__(self, x, y, z, value, power=2):
97
+ self.x = x
98
+ self.y = y
99
+ self.z = z
100
+ self.value = value
101
+ self.power = power
102
+
103
+ def execute(self, point_x, point_y, point_z):
104
+ numerator = 0
105
+ denominator = 0
106
+
107
+ for i, (x, y, z, val) in enumerate(zip(self.x, self.y, self.z, self.value)):
108
+ d = (
109
+ (x - point_x) ** 2 + (y - point_y) ** 2 + (z - point_z) ** 2
110
+ ) ** 0.5
111
+ if d == 0:
112
+ return val, 0
113
+ weight = 1 / (d**self.power)
114
+ numerator += weight * val
115
+ denominator += weight
116
+
117
+ result = numerator / denominator
118
+ return result, 0
119
+
120
+ def fit(self, data):
121
+ arr = np.asarray(data)
122
+ if arr.ndim != 2 or arr.shape[1] != 4:
123
+ raise ValueError("输入数据必须是4列:[x, y, z, value]")
124
+ x, y, z, value = arr[:, 0], arr[:, 1], arr[:, 2], arr[:, 3]
125
+ self.model = self.IDWModel(x.tolist(), y.tolist(), z.tolist(), value.tolist())
126
+ return self
127
+
128
+ def predict(self, points):
129
+ arr = np.asarray(points)
130
+ if arr.ndim == 1:
131
+ x, y, z = float(arr[0]), float(arr[1]), float(arr[2])
132
+ result, _ = self.model.execute(x, y, z)
133
+ return result
134
+ elif arr.ndim == 2 and arr.shape[1] == 3:
135
+ z1 = np.zeros(arr.shape[0], dtype=float)
136
+ for i in range(arr.shape[0]):
137
+ z1[i], _ = self.model.execute(
138
+ float(arr[i, 0]), float(arr[i, 1]), float(arr[i, 2])
139
+ )
140
+ return z1
141
+ else:
142
+ raise ValueError("预测点坐标必须是3列:[x, y, z] 或形状 (M, 3)")
143
+
144
+ def loss(self, data, res):
145
+ return ErrorMetrics.mse(data, res)