Metadata-Version: 2.2
Name: gismath
Version: 0.1.7
Summary: Add your description here
Requires-Python: >=3.11
Requires-Dist: numpy>=2.0
Description-Content-Type: text/markdown

# gismath

## 安装

> pip install gismath


## 示例

```python
import gismath

lon, lat, alt = 121.57156751580956, 31.287623375403385, 0.15180000000691507

# c++ 实现
ecef_cpp = gismath.geodetic2ecef_cpp(lon, lat, alt)

# cython 实现
ecef_cy = gismath.geodetic2ecef_cy(lon, lat, alt)

print(ecef_cpp)
>>> [-2856298.1505069532, 4648013.005657461, 3293186.773949799]

print(ecef_cy)
>>> (-2856298.1505069532, 4648013.005657461, 3293186.773949799)
```

提供常用 GIS 算法的 CPP 版本和 Cython 版本



| 测试                        | CPP 版耗时   | Cython 版耗时 | numba.njit 耗时 | numba.njit(fastmath=True) 耗时 | Pure Python 3.11.3 |
| --------------------------- | ------------ | ------------- | --------------- | ------------------------------ | ------------------ |
| 经纬度转ECEF（50000000 条） | 16.043000 秒 | 08.345999 秒  | 14.576452 秒    | 10.386999 秒                   | 40.454000 秒       |
|                             |              |               |                 |                                |                    |
|                             |              |               |                 |                                |                    |

---

## 批量接口（推荐用于大数据量）

标量接口逐点调用会被 Python 的函数调用开销拖垮。处理成千上万个点时，
**一律使用 `*_fast_array` 系列**——它们内部用 OpenMP `prange` 多线程 + AVX2/FMA
向量化，一次调用处理整个数组。

输入输出统一为 `(N, 3)` 的 `float64` numpy 数组，且要求 C 连续。

| 函数 | 输入每行 | 输出每行 |
| --- | --- | --- |
| `geodetic2ecef_fast_array(arr)` | `[经度(度), 纬度(度), 高程(米)]` | ECEF `[X, Y, Z]`（米） |
| `geodetic_to_web_mercator_fast_array(arr)` | `[经度(度), 纬度(度), 高程(米)]` | `[x, y, z]`（EPSG:3857 米） |
| `web_mercator_to_geodetic_fast_array(arr)` | `[x, y, z]`（EPSG:3857 米） | `[经度(度), 纬度(度), 高程(米)]` |
| `web_mercator_to_ecef_fast_array(arr)` | `[x, y, z]`（EPSG:3857 米） | ECEF `[X, Y, Z]`（米） |

```python
import numpy as np
import gismath

lla = np.array([
    [121.57156751580956, 31.287623375403385, 0.1518],
    [116.39123456,       39.90600000,        43.5  ],
], dtype=np.float64)

ecef = gismath.geodetic2ecef_fast_array(lla)

# EPSG:3857 -> ECEF：一步到位，内部全程用弧度，
# 省去 rad->deg->rad 的往返与一次中间数组分配
merc = gismath.geodetic_to_web_mercator_fast_array(lla)
ecef2 = gismath.web_mercator_to_ecef_fast_array(merc)
```

`ecef2geodetic_np_cy(pos_array, transform=np.eye(4), return_z=False)` 提供 ECEF 转经纬度的
批量版本，可选地先应用一个 4×4 变换矩阵。

---

## 角度单位约定

**所有对外接口的经纬度一律使用「度」**，包括 Web Mercator 系列的输入与输出。
因此下面两种写法等价，可直接串联：

```python
lon, lat, alt = 121.5, 31.2, 0.0

# 直接转
a = gismath.geodetic2ecef_cpp(lon, lat, alt)

# 经 Web Mercator 中转
x, y, z = gismath.geodetic_to_web_mercator_cpp(lon, lat, alt)
b = gismath.geodetic2ecef_cpp(*gismath.web_mercator_to_geodetic_cpp(x, y, z))
```

> 0.1.7 之前的版本存在两个缺陷：`webMercatorToGeodetic` 返回的是**弧度**而非度，
> 且 `geodeticToWebMercator` 把输入当作弧度处理，导致上面两种写法结果不一致；
> 同时三个 C++ 接口因 `std::vector<double> v(3)` 后又 `push_back`，
> 实际返回 **6 个元素**（前 3 个恒为 0）。两者均已修复。

---

## 本机构建（VS 2026 + 较旧 CMake）

若本机的 Visual Studio 版本比 CMake 支持的 generator 更新（例如 VS 2026 + CMake 3.25，
CMake 最高只认识 `Visual Studio 17 2022`），直接 `uv build` 会失败。
此时用本机专用脚本，它会自动探测 VS、导入 MSVC 环境并强制使用 Ninja generator：

```powershell
.\scripts\build_local_wheels_homepc.ps1                          # Windows，cp311-cp314
.\scripts\build_local_wheels_homepc.ps1 -PythonVersions 3.11     # 只构建 3.11
.\scripts\build_local_wheels_homepc.ps1 -Platform linux          # Docker + cibuildwheel
.\scripts\build_local_wheels_homepc.ps1 -Platform all -Clean
```

---

## 测试

```bash
pytest test/
```

`test/test_web_mercator.py` 覆盖返回值长度、角度单位、批量与标量一致性、
多线程正确性，并在安装了 `pyproj` 时做交叉验证。
