|
36 | 36 | _populate_face_centroids, |
37 | 37 | _populate_node_latlon, |
38 | 38 | _populate_node_xyz, |
39 | | - _prepare_points_for_kdtree, |
40 | 39 | _set_desired_longitude_range, |
| 40 | + points_atleast_2d_xyz, |
41 | 41 | prepare_points, |
42 | 42 | ) |
43 | 43 | from uxarray.grid.dual import construct_dual |
@@ -2560,72 +2560,77 @@ def get_faces_between_latitudes(self, lats: Tuple[float, float]): |
2560 | 2560 |
|
2561 | 2561 | def get_faces_containing_point( |
2562 | 2562 | self, |
2563 | | - *, |
2564 | | - point_lonlat: Sequence[float] | np.ndarray = None, |
2565 | | - point_xyz: Sequence[float] | np.ndarray = None, |
| 2563 | + points: Sequence[float] | np.ndarray, |
2566 | 2564 | return_counts: bool = True, |
2567 | 2565 | ) -> Tuple[np.ndarray, np.ndarray] | List[List[int]]: |
2568 | 2566 | """ |
2569 | | - Identify which faces on the grid contain the given point(s). |
2570 | | -
|
2571 | | - Exactly one of `point_lonlat` or `point_xyz` must be provided. |
| 2567 | + Identify which grid faces contain the given point(s). |
2572 | 2568 |
|
2573 | 2569 | Parameters |
2574 | 2570 | ---------- |
2575 | | - point_lonlat : array_like of shape (2,), optional |
2576 | | - Longitude and latitude in **degrees**: (lon, lat). |
2577 | | - point_xyz : array_like of shape (3,), optional |
2578 | | - Cartesian coordinates on the unit sphere: (x, y, z). |
| 2571 | + points : array_like, shape (N, 2) or (2,) or shape (N, 3) or (3,) |
| 2572 | + Query point(s) to locate on the grid. |
| 2573 | + - If last dimension is 2, interpreted as (longitude, latitude) in **degrees**. |
| 2574 | + - If last dimension is 3, interpreted as Cartesian coordinates on the unit sphere: (x, y, z). |
| 2575 | + You may pass a single point (shape `(2,)` or `(3,)`) or multiple points (shape `(N, 2)` or `(N, 3)`). |
2579 | 2576 | return_counts : bool, default=True |
2580 | | - - If True (default), returns a tuple `(face_indices, counts)`. |
2581 | | - - If False, returns a `list` of per-point lists of face indices. |
| 2577 | + - If True, returns a tuple `(face_indices, counts)`. |
| 2578 | + - If False, returns a `list` of per-point lists of face indices (no padding). |
2582 | 2579 |
|
2583 | 2580 | Returns |
2584 | 2581 | ------- |
2585 | 2582 | If `return_counts=True`: |
2586 | | - face_indices : np.ndarray, shape (N, M) or (N,) |
2587 | | - - 2D array of face indices with unused slots are filled with `INT_FILL_VALUE`. |
| 2583 | + face_indices : np.ndarray, shape (N, M) or (N, 1) |
| 2584 | + 2D array of face indices. Rows are padded with `INT_FILL_VALUE` when a point |
| 2585 | + lies on corners of multiple faces. If every queried point falls in exactly |
| 2586 | + one face, the result has shape `(N, 1)`. |
2588 | 2587 | counts : np.ndarray, shape (N,) |
2589 | | - Number of valid face indices in each row of `face_indices`. |
| 2588 | + Number of valid face indices in each row of `face_indices`. |
2590 | 2589 |
|
2591 | 2590 | If `return_counts=False`: |
2592 | 2591 | List[List[int]] |
2593 | | - A Python list of length `N`, where each element is the |
2594 | | - list of face indices (no padding) for that query point. |
| 2592 | + Python list of length `N`, where each element is the list of face |
| 2593 | + indices for that point (no padding, in natural order). |
2595 | 2594 |
|
2596 | 2595 | Notes |
2597 | 2596 | ----- |
2598 | | - - **Most** points will lie strictly inside exactly one face: |
2599 | | - in that common case, `counts == 1` and the returned |
2600 | | - `face_indices` can be collapsed to shape `(N,)`, with no padding. |
2601 | | - - If a point falls exactly on a corner shared by multiple faces, |
2602 | | - multiple face indices will appear in the first columns of each row; |
2603 | | - the remainder of each row is filled with `INT_FILL_VALUE`. |
| 2597 | + - Most points will lie strictly inside exactly one face; in that case, |
| 2598 | + `counts == 1` and `face_indices` has one column. |
| 2599 | + - Points that lie exactly on a vertex or edge shared by multiple faces |
| 2600 | + return multiple indices in the first `counts[i]` columns of row `i`, |
| 2601 | + with any remaining columns filled by `INT_FILL_VALUE`. |
| 2602 | +
|
2604 | 2603 |
|
2605 | 2604 | Examples |
2606 | 2605 | -------- |
2607 | | - >>> import uxarray as ux |
2608 | | - >>> grid_path = "/path/to/grid.nc" |
2609 | | - >>> uxgrid = ux.open_grid(grid_path) |
2610 | 2606 |
|
2611 | | - # 1. Query a Spherical (lon/lat) point |
2612 | | - >>> indices, counts = uxgrid.get_faces_containing_point(point_lonlat=(0.0, 0.0)) |
| 2607 | + Query a single spherical point |
2613 | 2608 |
|
2614 | | - # 2. Query a Cartesian (xyz) point |
2615 | | - >>> indices, counts = uxgrid.get_faces_containing_point( |
2616 | | - ... point_xyz=(0.0, 0.0, 1.0) |
2617 | | - ... ) |
| 2609 | + >>> face_indices, counts = uxgrid.get_faces_containing_point(points=(0.0, 0.0)) |
| 2610 | +
|
| 2611 | + Query a single Cartesian point |
| 2612 | +
|
| 2613 | + >>> face_indices, counts = uxgrid.get_faces_containing_point( |
| 2614 | + ... points=[0.0, 0.0, 1.0] |
| 2615 | + ... ) |
2618 | 2616 |
|
2619 | | - # 3. Return indices as a list of lists (no counts nor padding) |
2620 | | - >>> indices = uxgrid.get_faces_containing_point( |
2621 | | - ... point_xyz=(0.0, 0.0, 1.0), return_counts=False |
| 2617 | + Query multiple points at once |
| 2618 | +
|
| 2619 | + >>> pts = [(0.0, 0.0), (10.0, 20.0)] |
| 2620 | + >>> face_indices, counts = uxgrid.get_faces_containing_point(points=pts) |
| 2621 | +
|
| 2622 | + Return a list of lists |
| 2623 | +
|
| 2624 | + >>> face_indices_list = uxgrid.get_faces_containing_point( |
| 2625 | + ... points=[0.0, 0.0, 1.0], return_counts=False |
2622 | 2626 | ... ) |
2623 | | - """ |
2624 | 2627 |
|
2625 | | - pts = _prepare_points_for_kdtree(point_lonlat, point_xyz) |
| 2628 | + """ |
2626 | 2629 |
|
2627 | 2630 | # Determine faces containing points |
2628 | | - face_indices, counts = _point_in_face_query(source_grid=self, points=pts) |
| 2631 | + face_indices, counts = _point_in_face_query( |
| 2632 | + source_grid=self, points=points_atleast_2d_xyz(points) |
| 2633 | + ) |
2629 | 2634 |
|
2630 | 2635 | # Return a list of lists if counts are not desired |
2631 | 2636 | if not return_counts: |
|
0 commit comments