rustmap3d 0.2.3__cp314-cp314-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.
rustmap3d/__init__.py ADDED
@@ -0,0 +1,5 @@
1
+ from .rustmap3d import *
2
+
3
+ __doc__ = rustmap3d.__doc__
4
+ if hasattr(rustmap3d, "__all__"):
5
+ __all__ = rustmap3d.__all__
rustmap3d/__init__.pyi ADDED
@@ -0,0 +1,855 @@
1
+ # This file is automatically generated by pyo3_stub_gen
2
+ # ruff: noqa: E501, F401
3
+
4
+ import builtins
5
+
6
+ def aer2ecef(
7
+ a_d: builtins.float,
8
+ e_d: builtins.float,
9
+ r_m: builtins.float,
10
+ lat_ref_d: builtins.float,
11
+ lon_ref_d: builtins.float,
12
+ ) -> tuple[builtins.float, builtins.float, builtins.float]:
13
+ r"""
14
+ Converts AER from a given lat/lon to a new ECEF location
15
+
16
+ # Arguments
17
+
18
+ * `a_d` - Azimuth in degrees [float]
19
+ * `e_d` - Elevation in degrees [float]
20
+ * `r_m` - Range in meters [float]
21
+ * `lat_ref_d` - Reference WGS84 Lat in degrees [float]
22
+ * `lon_ref_d` - Reference WGS84 Lon in degrees [float]
23
+
24
+ # Returns
25
+
26
+ * `ecef` - Absolute ECEF position in meters
27
+ """
28
+
29
+ def aer2ecef_uvw(
30
+ a_d: builtins.float,
31
+ e_d: builtins.float,
32
+ r_m: builtins.float,
33
+ lat_ref_d: builtins.float,
34
+ lon_ref_d: builtins.float,
35
+ ) -> tuple[builtins.float, builtins.float, builtins.float]:
36
+ r"""
37
+ Converts a vector direction and distance given in AER to ECEF uvw
38
+
39
+ # Arguments
40
+
41
+ * `a_d` - Azimuth in degrees [float]
42
+ * `e_d` - Elevation in degrees [float]
43
+ * `r_m` - Range in meters [float]
44
+ * `lat_ref_d` - Reference WGS84 Lat in degrees [float]
45
+ * `lon_ref_d` - Reference WGS84 Lon in degrees [float]
46
+
47
+ # Returns
48
+
49
+ * `ecef_uvw` - Vector represented in ECEF frame. Not an absolute position [[meters]].
50
+ """
51
+
52
+ def aer2enu(
53
+ a_d: builtins.float, e_d: builtins.float, r_m: builtins.float
54
+ ) -> tuple[builtins.float, builtins.float, builtins.float]:
55
+ r"""
56
+ Converts AER vector direction and magnitude to ENU.
57
+
58
+ # Arguments
59
+
60
+ * `a_d` - Azimuth in degrees [float]
61
+ * `e_d` - Elevation in degrees [float]
62
+ * `r_m` - Range in meters [float]
63
+
64
+ # Returns
65
+
66
+ * `enu` - Vector represented in ENU coordinates [meters].
67
+ """
68
+
69
+ def aer2ned(
70
+ a_d: builtins.float, e_d: builtins.float, r_m: builtins.float
71
+ ) -> tuple[builtins.float, builtins.float, builtins.float]:
72
+ r"""
73
+ Converts AER vector direction and magnitude to NED.
74
+
75
+ # Arguments
76
+
77
+ * `a_d` - Azimuth in degrees [float]
78
+ * `e_d` - Elevation in degrees [float]
79
+ * `r_m` - Range in meters [float]
80
+
81
+ # Returns
82
+
83
+ * `ned` - Vector represented in NED coordinates [meters].
84
+ """
85
+
86
+ def angle_between(
87
+ ax: builtins.float,
88
+ ay: builtins.float,
89
+ az: builtins.float,
90
+ bx: builtins.float,
91
+ by: builtins.float,
92
+ bz: builtins.float,
93
+ ) -> builtins.float:
94
+ r"""
95
+ Computes the angle between two vectors in radians. Dot product is clamped to [-1, 1] so this always outputs a number
96
+
97
+ # Arguments
98
+
99
+ * `ax` - a vector x [float]
100
+ * `ay` - a vector y [float]
101
+ * `az` - a vector z [float]
102
+ * `bx` - b vector x [float]
103
+ * `by` - b vector y [float]
104
+ * `bz` - b vector z [float]
105
+
106
+ # Returns
107
+
108
+ * `angle` - angle between the two vectors in radians
109
+ """
110
+
111
+ def dd2dms(dd: builtins.float, is_lat: builtins.bool) -> builtins.str:
112
+ r"""
113
+ Converts decimal degrees (DD) to degrees-minutes-seconds (DMS).
114
+
115
+ # Arguments
116
+
117
+ * `dd` - Decimal degrees [degrees].
118
+ * `is_lat` - Flag to denote if this decimal value describes a latitude [bool]
119
+
120
+ # Returns
121
+
122
+ * `dms` - Format "{Degrees}:{Minutes}:{Seconds}.{DecSeconds}{Direction}" where Direction is one of N, E, S, or W.
123
+
124
+ # Examples
125
+ ```
126
+ dms = map3d.dd2dms(25.37909389, true) #> "25:22:44.738N"
127
+ ```
128
+ """
129
+
130
+ def dms2dd(dms: builtins.str) -> builtins.float:
131
+ r"""
132
+ Converts degrees-minutes-seconds (DMS) to decimal degrees (DD).
133
+
134
+ # Arguments
135
+
136
+ * `dms` - Format "{Degrees}:{Minutes}:{Seconds}.{DecSeconds}{Direction}" where Direction is one of N, E, S, or W.
137
+
138
+ # Returns
139
+
140
+ * `dd` - Decimal degrees [degrees].
141
+
142
+ # Examples
143
+ ```
144
+ dd = map3d.dms2dd("25:22:44.738N") #> 25.37909389
145
+ ```
146
+ """
147
+
148
+ def ecef2aer(
149
+ x_m: builtins.float,
150
+ y_m: builtins.float,
151
+ z_m: builtins.float,
152
+ lat_ref_d: builtins.float,
153
+ lon_ref_d: builtins.float,
154
+ ) -> tuple[builtins.float, builtins.float, builtins.float]:
155
+ r"""
156
+ Converts an absolute ECEF to AER (az el range).
157
+
158
+ # Arguments
159
+
160
+ * `x_m` - ECEF x in meters [float]
161
+ * `y_m` - ECEF y in meters [float]
162
+ * `z_m` - ECEF z in meters [float]
163
+ * `lat_ref_d` - Reference WGS84 Lat in degrees [float]
164
+ * `lon_ref_d` - Reference WGS84 Lon in degrees [float]
165
+
166
+ # Returns
167
+
168
+ * `aer` - Vector represented in AER coordinates [degrees-degrees-meters].
169
+ """
170
+
171
+ def ecef2enu(
172
+ x_m: builtins.float,
173
+ y_m: builtins.float,
174
+ z_m: builtins.float,
175
+ lat_ref_d: builtins.float,
176
+ lon_ref_d: builtins.float,
177
+ ) -> tuple[builtins.float, builtins.float, builtins.float]:
178
+ r"""
179
+ Converts an ECEF position to ENU.
180
+
181
+ # Arguments
182
+
183
+ * `x_m` - ECEF x in meters [float]
184
+ * `y_m` - ECEF y in meters [float]
185
+ * `z_m` - ECEF z in meters [float]
186
+ * `lat_ref_d` - Reference WGS84 Lat in degrees [float]
187
+ * `lon_ref_d` - Reference WGS84 Lon in degrees [float]
188
+
189
+ # Returns
190
+
191
+ * `enu` - Vector represented in ENU coordinates [meters].
192
+ """
193
+
194
+ def ecef2enu_dcm(
195
+ lat_d: builtins.float, lon_d: builtins.float
196
+ ) -> tuple[
197
+ builtins.float,
198
+ builtins.float,
199
+ builtins.float,
200
+ builtins.float,
201
+ builtins.float,
202
+ builtins.float,
203
+ builtins.float,
204
+ builtins.float,
205
+ builtins.float,
206
+ ]:
207
+ r"""
208
+ Calculates the direction cosine matrix that yields an ECEF to ENU transformation at this LLA.
209
+
210
+ # Arguments
211
+
212
+ * `lat_d` - Latitude reference in degrees [float].
213
+ * `lon_d` - Longitude reference in degrees [float].
214
+
215
+ # Returns
216
+
217
+ * `dcm` - ECEF to ENU direction cosine matrix [[xx, xy, xz], [yx, yy, yz], [zx, zy, zz]]
218
+ """
219
+
220
+ def ecef2enu_quat(
221
+ lat_d: builtins.float, lon_d: builtins.float
222
+ ) -> tuple[builtins.float, builtins.float, builtins.float, builtins.float]:
223
+ r"""
224
+ Calculates the quaternion that yields an ECEF to ENU transformation at this LLA.
225
+
226
+ # Arguments
227
+
228
+ * `lat_d` - Latitude reference in degrees [float].
229
+ * `lon_d` - Longitude reference in degrees [float].
230
+
231
+ # Returns
232
+
233
+ * `quat` - Normalized ECEF to ENU quaternion.
234
+ """
235
+
236
+ def ecef2lla(
237
+ x_m: builtins.float, y_m: builtins.float, z_m: builtins.float
238
+ ) -> tuple[builtins.float, builtins.float, builtins.float]:
239
+ r"""
240
+ Converts ECEF to WGS84 LLA
241
+
242
+ # Arguments
243
+
244
+ * `x_m` - ECEF x in meters [float]
245
+ * `y_m` - ECEF y in meters [float]
246
+ * `z_m` - ECEF z in meters [float]
247
+
248
+ # Returns
249
+
250
+ * `lla` - Vector represented in WGS84 LLA [degrees-degrees-meters].
251
+ """
252
+
253
+ def ecef2ned(
254
+ x_m: builtins.float,
255
+ y_m: builtins.float,
256
+ z_m: builtins.float,
257
+ lat_ref_d: builtins.float,
258
+ lon_ref_d: builtins.float,
259
+ ) -> tuple[builtins.float, builtins.float, builtins.float]:
260
+ r"""
261
+ Converts an absolute ECEF location to NED.
262
+
263
+ # Arguments
264
+
265
+ * `x_m` - ECEF x in meters [float]
266
+ * `y_m` - ECEF y in meters [float]
267
+ * `z_m` - ECEF z in meters [float]
268
+ * `lat_ref_d` - Reference WGS84 Lat in degrees [float]
269
+ * `lon_ref_d` - Reference WGS84 Lon in degrees [float]
270
+
271
+ # Returns
272
+
273
+ * `ned` - Vector represented in NED coordinates [meters].
274
+ """
275
+
276
+ def ecef2ned_dcm(
277
+ lat_d: builtins.float, lon_d: builtins.float
278
+ ) -> tuple[
279
+ builtins.float,
280
+ builtins.float,
281
+ builtins.float,
282
+ builtins.float,
283
+ builtins.float,
284
+ builtins.float,
285
+ builtins.float,
286
+ builtins.float,
287
+ builtins.float,
288
+ ]:
289
+ r"""
290
+ Calculates the direction cosine matrix that yields an ECEF to NED transformation at this LLA.
291
+
292
+ # Arguments
293
+
294
+ * `lat_d` - Latitude reference in degrees [float].
295
+ * `lon_d` - Longitude reference in degrees [float].
296
+
297
+ # Returns
298
+
299
+ * `dcm` - ECEF to NED direction cosine matrix [[xx, xy, xz], [yx, yy, yz], [zx, zy, zz]]
300
+ """
301
+
302
+ def ecef2ned_quat(
303
+ lat_d: builtins.float, lon_d: builtins.float
304
+ ) -> tuple[builtins.float, builtins.float, builtins.float, builtins.float]:
305
+ r"""
306
+ Calculates the quaternion that yields an ECEF to NED transformation at this LLA.
307
+
308
+ # Arguments
309
+
310
+ * `lat_d` - Latitude reference in degrees [float].
311
+ * `lon_d` - Longitude reference in degrees [float].
312
+
313
+ # Returns
314
+
315
+ * `quat` - Normalized ECEF to NED quaternion (w, x, y, z).
316
+ """
317
+
318
+ def ecef_quat2heading(
319
+ w: builtins.float,
320
+ x: builtins.float,
321
+ y: builtins.float,
322
+ z: builtins.float,
323
+ lat_ref_d: builtins.float,
324
+ lon_ref_d: builtins.float,
325
+ ) -> builtins.float:
326
+ r"""
327
+ Computes the clockwise angle from North of a local body-frame's x-axis
328
+
329
+ # Arguments
330
+
331
+ * `w` - Scalar part of quaternion [float]
332
+ * `x` - x part of quaternion [float]
333
+ * `y` - y part of quaternion [float]
334
+ * `z` - z part of quaternion [float]
335
+ * `lat_ref_d` - Reference WGS84 Lat in degrees [float]
336
+ * `lon_ref_d` - Reference WGS84 Lon in degrees [float]
337
+
338
+ # Returns
339
+
340
+ * `heading` - Clockwise angle off true north [[degrees]] of the body's x axis
341
+ """
342
+
343
+ def ecef_uvw2aer(
344
+ u_m: builtins.float,
345
+ v_m: builtins.float,
346
+ w_m: builtins.float,
347
+ lat_ref_d: builtins.float,
348
+ lon_ref_d: builtins.float,
349
+ ) -> tuple[builtins.float, builtins.float, builtins.float]:
350
+ r"""
351
+ Converts ECEF uvw to AER (az el range).
352
+
353
+ # Arguments
354
+
355
+ * `u_m` - ECEF u in meters [float]
356
+ * `v_m` - ECEF v in meters [float]
357
+ * `w_m` - ECEF w in meters [float]
358
+ * `lat_ref_d` - Reference WGS84 Lat in degrees [float]
359
+ * `lon_ref_d` - Reference WGS84 Lon in degrees [float]
360
+
361
+ # Returns
362
+
363
+ * `aer` - Vector represented in AER coordinates [degrees-degrees-meters].
364
+ """
365
+
366
+ def ecef_uvw2enu(
367
+ u_m: builtins.float,
368
+ v_m: builtins.float,
369
+ w_m: builtins.float,
370
+ lat_ref_d: builtins.float,
371
+ lon_ref_d: builtins.float,
372
+ ) -> tuple[builtins.float, builtins.float, builtins.float]:
373
+ r"""
374
+ Converts an ECEF uvw vector to ENU.
375
+
376
+ # Arguments
377
+
378
+ * `u_m` - ECEF u in meters [float]
379
+ * `v_m` - ECEF v in meters [float]
380
+ * `w_m` - ECEF w in meters [float]
381
+ * `lat_ref_d` - Reference WGS84 Lat in degrees [float]
382
+ * `lon_ref_d` - Reference WGS84 Lon in degrees [float]
383
+
384
+ # Returns
385
+
386
+ * `enu` - Vector represented in ENU coordinates [meters].
387
+ """
388
+
389
+ def ecef_uvw2ned(
390
+ u_m: builtins.float,
391
+ v_m: builtins.float,
392
+ w_m: builtins.float,
393
+ lat_ref_d: builtins.float,
394
+ lon_ref_d: builtins.float,
395
+ ) -> tuple[builtins.float, builtins.float, builtins.float]:
396
+ r"""
397
+ Converts ECEF UVW Vector to NED.
398
+
399
+ # Arguments
400
+
401
+ * `u_m` - ECEF u in meters [float]
402
+ * `v_m` - ECEF v in meters [float]
403
+ * `w_m` - ECEF w in meters [float]
404
+ * `lat_ref_d` - Reference WGS84 Lat in degrees [float]
405
+ * `lon_ref_d` - Reference WGS84 Lon in degrees [float]
406
+
407
+ # Returns
408
+
409
+ * `ned` - Vector represented in NED coordinates [meters].
410
+ """
411
+
412
+ def enu2aer(
413
+ e_m: builtins.float, n_m: builtins.float, u_m: builtins.float
414
+ ) -> tuple[builtins.float, builtins.float, builtins.float]:
415
+ r"""
416
+ Converts ENU to AER.
417
+
418
+ # Arguments
419
+
420
+ * `e_m` - East in meters [float]
421
+ * `n_m` - North in meters [float]
422
+ * `u_m` - Up in meters [float]
423
+
424
+ # Returns
425
+
426
+ * `aer` - Vector represented in AER coordinates [degrees-degrees-meters].
427
+ """
428
+
429
+ def enu2ecef(
430
+ e_m: builtins.float,
431
+ n_m: builtins.float,
432
+ u_m: builtins.float,
433
+ lat_ref_d: builtins.float,
434
+ lon_ref_d: builtins.float,
435
+ ) -> tuple[builtins.float, builtins.float, builtins.float]:
436
+ r"""
437
+ Converts ENU to an ECEF position
438
+
439
+ # Arguments
440
+
441
+ * `e_m` - East in meters [float]
442
+ * `n_m` - North in meters [float]
443
+ * `u_m` - Up in meters [float]
444
+ * `lat_ref_d` - Reference WGS84 Lat in degrees [float]
445
+ * `lon_ref_d` - Reference WGS84 Lon in degrees [float]
446
+
447
+ # Returns
448
+
449
+ * `ecef` - Absolute ECEF position in meters
450
+ """
451
+
452
+ def enu2ecef_dcm(
453
+ lat_d: builtins.float, lon_d: builtins.float
454
+ ) -> tuple[
455
+ builtins.float,
456
+ builtins.float,
457
+ builtins.float,
458
+ builtins.float,
459
+ builtins.float,
460
+ builtins.float,
461
+ builtins.float,
462
+ builtins.float,
463
+ builtins.float,
464
+ ]:
465
+ r"""
466
+ Calculates the direction cosine matrix that yields an ENU to ECEF transformation at this LLA.
467
+
468
+ # Arguments
469
+
470
+ * `lat_d` - Latitude reference in degrees [float].
471
+ * `lon_d` - Longitude reference in degrees [float].
472
+
473
+ # Returns
474
+
475
+ * `dcm` - ENU to ECEF direction cosine matrix [[xx, xy, xz], [yx, yy, yz], [zx, zy, zz]]
476
+ """
477
+
478
+ def enu2ecef_quat(
479
+ lat_d: builtins.float, lon_d: builtins.float
480
+ ) -> tuple[builtins.float, builtins.float, builtins.float, builtins.float]:
481
+ r"""
482
+ Calculates the quaternion that yields an ENU to ECEF transformation at this LLA.
483
+
484
+ # Arguments
485
+
486
+ * `lat_d` - Latitude reference in degrees [float].
487
+ * `lon_d` - Longitude reference in degrees [float].
488
+
489
+ # Returns
490
+
491
+ * `quat` - Normalized ENU to ECEF quaternion (w, x, y, z).
492
+ """
493
+
494
+ def enu2ecef_uvw(
495
+ e_m: builtins.float,
496
+ n_m: builtins.float,
497
+ u_m: builtins.float,
498
+ lat_ref_d: builtins.float,
499
+ lon_ref_d: builtins.float,
500
+ ) -> tuple[builtins.float, builtins.float, builtins.float]:
501
+ r"""
502
+ Converts ENU to ECEF uvw vector
503
+
504
+ # Arguments
505
+
506
+ * `e_m` - East in meters [float]
507
+ * `n_m` - North in meters [float]
508
+ * `u_m` - Up in meters [float]
509
+ * `lat_ref_d` - Reference WGS84 Lat in degrees [float]
510
+ * `lon_ref_d` - Reference WGS84 Lon in degrees [float]
511
+
512
+ # Returns
513
+
514
+ * `ecef_uvw` - Vector represented in ECEF frame. Not an absolute position [[meters]].
515
+ """
516
+
517
+ def enu2heading(
518
+ e_m: builtins.float, n_m: builtins.float, u_m: builtins.float
519
+ ) -> builtins.float:
520
+ r"""
521
+ Calculates heading angle from ENU.
522
+
523
+ # Arguments
524
+
525
+ * `e_m` - East in meters [float]
526
+ * `n_m` - North in meters [float]
527
+ * `u_m` - Up in meters [float]
528
+
529
+ # Returns
530
+
531
+ * `heading_deg` - Heading angle relative to true north [degrees].
532
+ """
533
+
534
+ def enu2lla(
535
+ e_m: builtins.float,
536
+ n_m: builtins.float,
537
+ u_m: builtins.float,
538
+ lat_ref_d: builtins.float,
539
+ lon_ref_d: builtins.float,
540
+ ) -> tuple[builtins.float, builtins.float, builtins.float]:
541
+ r"""
542
+ Converts ENU to an absolute LLA position
543
+
544
+ # Arguments
545
+
546
+ * `e_m` - East in meters [float]
547
+ * `n_m` - North in meters [float]
548
+ * `u_m` - Up in meters [float]
549
+ * `lat_ref_d` - Reference WGS84 Lat in degrees [float]
550
+ * `lon_ref_d` - Reference WGS84 Lon in degrees [float]
551
+
552
+ # Returns
553
+
554
+ * `lla` - Absolute LLA position [deg-deg-m]
555
+ """
556
+
557
+ def ll2dms(
558
+ lat_d: builtins.float, lon_d: builtins.float
559
+ ) -> tuple[builtins.str, builtins.str]:
560
+ r"""
561
+ Convenience function to convert lat/lon to a tuple of (lat dms, lon dms)
562
+
563
+ # Arguments
564
+
565
+ * `lat` - Latitude in decimal degrees
566
+ * `lon` - Longitude in decimal degrees
567
+
568
+ # Returns
569
+
570
+ * `(lat dms, lon dms)` - Tuple of lat/lon as degrees:minutes:seconds [Tuple[String, String]]
571
+ ```
572
+ """
573
+
574
+ def lla2ecef(
575
+ lat_d: builtins.float, lon_d: builtins.float, alt_m: builtins.float
576
+ ) -> tuple[builtins.float, builtins.float, builtins.float]:
577
+ r"""
578
+ Converts WGS84 LLA to ECEF.
579
+
580
+ # Arguments
581
+
582
+ * `lat_d` - WGS84 Lat in degrees [float]
583
+ * `lon_d` - WGS84 Lon in degrees [float]
584
+ * `alt_m` - WGS84 MSL alt in meters [float]
585
+
586
+ # Returns
587
+
588
+ * `ecef` - Vector represented in ECEF coordinates [meters].
589
+ """
590
+
591
+ def lla2enu(
592
+ lat_d: builtins.float,
593
+ lon_d: builtins.float,
594
+ alt_m: builtins.float,
595
+ lat_ref_d: builtins.float,
596
+ lon_ref_d: builtins.float,
597
+ ) -> tuple[builtins.float, builtins.float, builtins.float]:
598
+ r"""
599
+ Converts an absolute LLA position to an ENU vector relative to a lla reference
600
+
601
+ # Arguments
602
+
603
+ * `lat_d` - WGS84 Lat in degrees [float]
604
+ * `lon_d` - WGS84 Lon in degrees [float]
605
+ * `alt_m` - WGS84 MSL alt in meters [float]
606
+ * `lat_ref_d` - Reference WGS84 Lat in degrees [float]
607
+ * `lon_ref_d` - Reference WGS84 Lon in degrees [float]
608
+
609
+ # Returns
610
+
611
+ * `enu` - Vector represented in ENU coordinates [meters].
612
+ """
613
+
614
+ def lla2ned(
615
+ lat_d: builtins.float,
616
+ lon_d: builtins.float,
617
+ alt_m: builtins.float,
618
+ lat_ref_d: builtins.float,
619
+ lon_ref_d: builtins.float,
620
+ ) -> tuple[builtins.float, builtins.float, builtins.float]:
621
+ r"""
622
+ Converts an absolute LLA location to a NED vector relative to a lla reference point
623
+
624
+ # Arguments
625
+
626
+ * `lat_d` - WGS84 Lat in degrees [float]
627
+ * `lon_d` - WGS84 Lon in degrees [float]
628
+ * `alt_m` - WGS84 MSL alt in meters [float]
629
+ * `lat_ref_d` - Reference WGS84 Lat in degrees [float]
630
+ * `lon_ref_d` - Reference WGS84 Lon in degrees [float]
631
+
632
+ # Returns
633
+
634
+ * `ned` - Vector represented in NED coordinates [meters].
635
+ """
636
+
637
+ def ned2aer(
638
+ n_m: builtins.float, e_m: builtins.float, d_m: builtins.float
639
+ ) -> tuple[builtins.float, builtins.float, builtins.float]:
640
+ r"""
641
+ Converts NED to AER.
642
+
643
+ # Arguments
644
+
645
+ * `n_m` - North in meters [float]
646
+ * `e_m` - East in meters [float]
647
+ * `d_m` - Down in meters [float]
648
+
649
+ # Returns
650
+
651
+ * `aer` - Vector represented in AER coordinates [degrees-degrees-meters].
652
+ """
653
+
654
+ def ned2ecef(
655
+ n_m: builtins.float,
656
+ e_m: builtins.float,
657
+ d_m: builtins.float,
658
+ lat_ref_d: builtins.float,
659
+ lon_ref_d: builtins.float,
660
+ ) -> tuple[builtins.float, builtins.float, builtins.float]:
661
+ r"""
662
+ Converts NED to an absolute ECEF location
663
+
664
+ # Arguments
665
+
666
+ * `n_m` - North in meters [float]
667
+ * `e_m` - East in meters [float]
668
+ * `d_m` - Down in meters [float]
669
+ * `lat_ref_d` - Reference WGS84 Lat in degrees [float]
670
+ * `lon_ref_d` - Reference WGS84 Lon in degrees [float]
671
+
672
+ # Returns
673
+
674
+ * `ecef` - Absolute ECEF position in meters
675
+ """
676
+
677
+ def ned2ecef_dcm(
678
+ lat_d: builtins.float, lon_d: builtins.float
679
+ ) -> tuple[
680
+ builtins.float,
681
+ builtins.float,
682
+ builtins.float,
683
+ builtins.float,
684
+ builtins.float,
685
+ builtins.float,
686
+ builtins.float,
687
+ builtins.float,
688
+ builtins.float,
689
+ ]:
690
+ r"""
691
+ Calculates the direction cosine matrix that yields an NED to ECEF transformation at this LLA.
692
+
693
+ # Arguments
694
+
695
+ * `lat_d` - Latitude reference in degrees [float].
696
+ * `lon_d` - Longitude reference in degrees [float].
697
+
698
+ # Returns
699
+
700
+ * `dcm` - NED to ECEF direction cosine matrix [[xx, xy, xz], [yx, yy, yz], [zx, zy, zz]]
701
+ """
702
+
703
+ def ned2ecef_quat(
704
+ lat_d: builtins.float, lon_d: builtins.float
705
+ ) -> tuple[builtins.float, builtins.float, builtins.float, builtins.float]:
706
+ r"""
707
+ Calculates the quaternion that yields an NED to ECEF transformation at this LLA.
708
+
709
+ # Arguments
710
+
711
+ * `lat_d` - Latitude reference in degrees [float].
712
+ * `lon_d` - Longitude reference in degrees [float].
713
+
714
+ # Returns
715
+
716
+ * `quat` - Normalized NED to ECEF quaternion (w, x, y, z).
717
+ """
718
+
719
+ def ned2ecef_uvw(
720
+ n_m: builtins.float,
721
+ e_m: builtins.float,
722
+ d_m: builtins.float,
723
+ lat_ref_d: builtins.float,
724
+ lon_ref_d: builtins.float,
725
+ ) -> tuple[builtins.float, builtins.float, builtins.float]:
726
+ r"""
727
+ Converts NED to ECEF uvw
728
+
729
+ # Arguments
730
+
731
+ * `n_m` - North in meters [float]
732
+ * `e_m` - East in meters [float]
733
+ * `d_m` - Down in meters [float]
734
+ * `lat_ref_d` - Reference WGS84 Lat in degrees [float]
735
+ * `lon_ref_d` - Reference WGS84 Lon in degrees [float]
736
+
737
+ # Returns
738
+
739
+ * `ecef_uvw` - Vector represented in ECEF frame. Not an absolute position [[meters]].
740
+ """
741
+
742
+ def ned2lla(
743
+ n_m: builtins.float,
744
+ e_m: builtins.float,
745
+ d_m: builtins.float,
746
+ lat_ref_d: builtins.float,
747
+ lon_ref_d: builtins.float,
748
+ ) -> tuple[builtins.float, builtins.float, builtins.float]:
749
+ r"""
750
+ Converts a NED vector to an absolute lat lon alt
751
+
752
+ # Arguments
753
+
754
+ * `n_m` - North in meters [float]
755
+ * `e_m` - East in meters [float]
756
+ * `d_m` - Down in meters [float]
757
+ * `lat_ref_d` - Reference WGS84 Lat in degrees [float]
758
+ * `lon_ref_d` - Reference WGS84 Lon in degrees [float]
759
+
760
+ # Returns
761
+
762
+ * `lla` - Absolute lat lon alt [deg-deg-m]
763
+ """
764
+
765
+ def rand_ecef() -> tuple[builtins.float, builtins.float, builtins.float]:
766
+ r"""
767
+ Generates a uniform random ECEF point on the surface of a spherical Earth.
768
+
769
+ # Returns
770
+
771
+ * `ecef` - Random ECEF location [meters].
772
+ """
773
+
774
+ def rand_lla() -> tuple[builtins.float, builtins.float, builtins.float]:
775
+ r"""
776
+ Generates a uniform random LLA point. Altitude is generated in the domain [0.0, 10000.0].
777
+
778
+ # Returns
779
+
780
+ * `lla` - Random LLA location [degrees-degrees-meters].
781
+ """
782
+
783
+ def rand_orientation() -> tuple[
784
+ builtins.float, builtins.float, builtins.float, builtins.float
785
+ ]:
786
+ r"""
787
+ Generates a random normalized quaternion.
788
+
789
+ # Returns
790
+
791
+ * `quat` - Random normalized quaternion (w, x, y, z).
792
+ """
793
+
794
+ def vincenty_direct(
795
+ lat_d: builtins.float,
796
+ lon_d: builtins.float,
797
+ range_m: builtins.float,
798
+ bearing_d: builtins.float,
799
+ atol: builtins.float = ...,
800
+ max_iters: builtins.int = ...,
801
+ ) -> tuple[builtins.float, builtins.float]:
802
+ r"""
803
+ Calculates the LLA location that is a fixed range and bearing from a reference LLA. This function uses an iterative
804
+ solution to determine outputs using the WGS84 ellipsoidal Earth model.
805
+
806
+ See reference:
807
+ https://en.wikipedia.org/wiki/Vincenty%27s_formulae.
808
+
809
+ # Arguments
810
+
811
+ * `lat_d` - Latitude reference in degrees [float].
812
+ * `lon_d` - Longitude reference in degrees [float].
813
+ * `range_m` - Range (i.e., distance) from point A to point B [meters].
814
+ * `bearing_d` - Bearing (i.e., azimuth) from point A to point B relative to true north [degrees].
815
+ * `abs_tol` - Absolute tolerance used for convergence.
816
+ * `max_iters` - Maximum possible number of iterations before early termination.
817
+
818
+ # Returns
819
+
820
+ A tuple `(lat_deg, lon_deg)` where:
821
+ * `lat_deg` - Latitude location [degrees].
822
+ * `lon_deg` - Longitude location [degrees].
823
+ """
824
+
825
+ def vincenty_inverse(
826
+ lat_a_deg: builtins.float,
827
+ lon_a_deg: builtins.float,
828
+ lat_b_deg: builtins.float,
829
+ lon_b_deg: builtins.float,
830
+ atol: builtins.float = ...,
831
+ max_iters: builtins.int = ...,
832
+ ) -> tuple[builtins.float, builtins.float, builtins.float]:
833
+ r"""
834
+ Calculates range and bearings between two latitude-longitude points. This function uses an iterative solution to
835
+ determine outputs using the WGS84 ellipsoidal Earth model.
836
+
837
+ See reference:
838
+ https://en.wikipedia.org/wiki/Vincenty%27s_formulae.
839
+
840
+ # Arguments
841
+
842
+ * `lat_a_deg` - Latitude point A [degrees].
843
+ * `lon_a_deg` - Longitude point A [degrees].
844
+ * `lat_b_deg` - Latitude point A [degrees].
845
+ * `lon_b_deg` - Longitude point A [degrees].
846
+ * `atol` - Absolute tolerance used for convergence.
847
+ * `max_iters` - Maximum possible number of iterations before early termination.
848
+
849
+ # Returns
850
+
851
+ A tuple `(range_m, bearing_ab_deg, bearing_ba_deg)` where:
852
+ * `range_m` - Range (i.e., distance) from point A to point B [meters].
853
+ * `bearing_ab_deg` - Bearing (i.e., azimuth) from point A to point B relative to true north [degrees].
854
+ * `bearing_ba_deg` - Bearing (i.e., azimuth) from point B to point A relative to true north [degrees].
855
+ """
rustmap3d/py.typed ADDED
File without changes
Binary file
@@ -0,0 +1,102 @@
1
+ Metadata-Version: 2.4
2
+ Name: rustmap3d
3
+ Version: 0.2.3
4
+ Classifier: Programming Language :: Rust
5
+ Classifier: Programming Language :: Python :: Implementation :: CPython
6
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
7
+ License-File: LICENSE
8
+ License-File: LICENSE
9
+ Summary: Python geodetic coordinate conversions written in rust
10
+ Author-email: weiler <lucas.l.weiler@leidos.com>, molnar <andrew.b.molnar@leidos.com>
11
+ Requires-Python: >=3.8
12
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
13
+ Project-URL: Homepage, https://github.com/lskyweiler/rustmap3d
14
+
15
+ # rustmap3d
16
+
17
+ [![License](https://img.shields.io/badge/license-MIT%2FApache-blue.svg)](https://github.com/lskyweiler/rustmap3d#license)
18
+ ![Python](https://img.shields.io/badge/Python_3.8_|_3.9_|_3.10_|_3.11_|_3.12_|_3.13-blue?logo=python&logoColor=fff)
19
+ [![PyPI](https://img.shields.io/badge/PyPI-3775A9?logo=pypi&logoColor=fff)](https://pypi.org/project/rustmap3d/)
20
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
21
+
22
+ <p align="center"><img src="docs/rustmap3d.logo.svg" width="300px" height="300px"/></p>
23
+
24
+ **Simple, fast, and ergonomic geodetic coordinate conversions**
25
+
26
+ ---
27
+ ### Installation
28
+ ```bash
29
+ # add to an existing project
30
+ uv add rustmap3d
31
+ # pip install it directly
32
+ uv pip install rustmap3d
33
+
34
+ # pip install without uv
35
+ pip install rustmap3d
36
+ ```
37
+ ---
38
+ ### Examples
39
+ ```python
40
+ import rustmap3d
41
+
42
+
43
+ # wgs84 geodetic conversions
44
+ lla = rustmap3d.ecef2lla(x, y, z)
45
+ ecef = rustmap3d.lla2ecef(lat, lon, alt)
46
+ ...
47
+
48
+ # local conversions
49
+ ecef_uvw = rustmap3d.enu2ecef_uvw(e, n, u, lat_ref, lon_ref)
50
+ ecef = rustmap3d.enu2ecef(e, n, u, lat_ref, lon_ref)
51
+ ecef_uvw = rustmap3d.ned2ecef_uvw(n, e, d, lat_ref, lon_ref)
52
+ ecef = rustmap3d.ned2ecef(n, e, d, lat_ref, lon_ref)
53
+ # enu, ned, aer
54
+ ...
55
+
56
+ # local rotations
57
+ enu_quat = rustmap3d.enu2ecef_quat(lat, lon)
58
+ enu_dcm = rustmap3d.enu2ecef_dcm(lat, lon)
59
+ # enu, ned
60
+
61
+ # Conversions
62
+ dd = rustmap3d.dms2dd("25:22:44.738N") #> 25.37909389
63
+ dms = rustmap3d.dd2dms(25.37909389, is_lat=true) #> "25:22:44.738N"
64
+ lat, lon = rustmap3d.ll2dms(25.37909389, -138.7895679) #> "25:22:44.738N", "138:47:22.444W"
65
+ ...
66
+
67
+ # distance functions
68
+ lat, lon = rustmap3d.vincenty_direct(lat_deg, lon_deg, range_m, bearing_deg)
69
+ range_m, bearing_ab, bearing_ba = rustmap3d.vincenty_inverse(lat_a, lon_a, lat_b, lon_b)
70
+ ```
71
+
72
+ ## Comparison with similar packages
73
+
74
+ - 🚀🚀 Blazingly fast - written in rust (see [benchmarks](#benchmarks))
75
+ - Zero dependencies
76
+ - Dead simple api modeled after [pymap3d](https://github.com/geospace-code/pymap3d) and [matlab](https://www.mathworks.com/matlabcentral/fileexchange/15285-geodetic-toolbox)
77
+ - Exposes rotations (both quaternions and 3x3 matrices)
78
+
79
+ ## Benchmarks
80
+
81
+ Compared to [pymap3d](https://github.com/geospace-code/pymap3d)
82
+ > Note: This is comparing single calls of python floats, not vectorized numpy performance. Vectorized batched conversions will be implemented in the future
83
+
84
+ - *~50x* faster for lla2ecef
85
+ - *~400x* faster for ecef2lla
86
+
87
+ <p align="center"><img src="docs/benchmarks.svg"></p>
88
+
89
+ ```bash
90
+ # Run benchmarks
91
+ uv run pytest --benchmark-histogram="./docs/benchmarks" bench/
92
+ ```
93
+
94
+ ## Build From Source
95
+
96
+ Uses standard [maturin](https://github.com/PyO3/maturin) build process
97
+
98
+ ```bash
99
+ uv run maturin build -r # build a whl
100
+ uv run maturin dev -r # build a dev package similar to -e
101
+ ```
102
+
@@ -0,0 +1,8 @@
1
+ rustmap3d/__init__.py,sha256=3KvRU840onBHW4lM0rI1gngSINaQf2XjWebzsEnLULo,119
2
+ rustmap3d/__init__.pyi,sha256=4VKlAGbeyYr2EYv0sVZBQk-wBYEDR0dUdNkBbZIPqZQ,22918
3
+ rustmap3d/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ rustmap3d/rustmap3d.cp314-win_amd64.pyd,sha256=G6FY4VEBR1KRFsmWJ02uN8ILirOfx5BpDybm713j1og,1792000
5
+ rustmap3d-0.2.3.dist-info/METADATA,sha256=tjFxvGNw7IA3zd2gFDcFQviGMhiRjTCu9U7Skg0BtgY,3429
6
+ rustmap3d-0.2.3.dist-info/WHEEL,sha256=TASrtxyeL-Pi7odwPBMCgR1YebCHdBFZvgqiADG_4b0,97
7
+ rustmap3d-0.2.3.dist-info/licenses/LICENSE,sha256=nPus_5ylrEEVZWLoXU2-Sz5VWnp4BPaNUt0bP2FY52o,1070
8
+ rustmap3d-0.2.3.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: maturin (1.11.5)
3
+ Root-Is-Purelib: false
4
+ Tag: cp314-cp314-win_amd64
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) [2025] [rustmap3d]
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.