Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .claude/sweep-style-state.csv
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module,last_inspected,issue,severity_max,categories_found,notes
aspect,2026-05-29,2683,MEDIUM,1,E402+E305 line 38: from xrspatial.geodesic import block sat below _geodesic_cuda_dims; moved up with top-of-file imports. E501 lines 219/263: wrapped two _run_gpu_geodesic_aspect kernel-launch calls (101/109 chars). Cat 4 isort reviewed but NOT applied: slope.py/curvature.py use one-import-per-line for xrspatial.utils so raw isort would make aspect inconsistent. Cat 2/3/5 grep clean. PR #2740. 82 aspect+geodesic tests pass.
contour,2026-05-29,2698,HIGH,3,"F821 line 557: contours() return annotation ""gpd.GeoDataFrame"" referenced gpd not bound at module scope (only imported inside _to_geopandas). Fixed via TYPE_CHECKING-guarded import geopandas as gpd, matching polygonize.py. No runtime change; geopandas stays optional. isort clean. Cat 1/2/4/5 clean. 24 contour tests pass. PR open."
cost_distance,2026-06-15,3339,HIGH,1;3;4;5,"Cat 3 F401: removed unused 'from functools import partial' (L32, refactor leftover, not re-exported). Cat 5 mutable default target_values: list = [] was found here too, but the parallel api-consistency PR #3348 fixed it first (same None-sentinel normalization, merged to main); on reconciliation this PR's duplicate source change and its two target_values tests were dropped, so PR #3350 is now lint-only. Cat 1: E302 L63 (1->2 blank lines before @ngjit _heap_push; placed blanks between comment divider and decorator to satisfy both E302 and isort) + E127 x5 (_cost_distance_dask_cupy L461-462, _cost_distance_dask_iterative L1005-1007 signature continuation over-indent). Cat 4 isort: dataset_support before utils, utils from-import reflowed to 100 cols. Cat 2 grep clean. flake8+isort clean on module after fix; cost_distance tests pass (CUDA available). Pre-existing test-file lint (F401 L314/L504, E201 L449, isort drift) left untouched - out of module scope. PR open."
focal,2026-05-29,2731,HIGH,3;4;5,"F401 not_implemented_func (import line 36, unused, not re-exported). isort: stdlib reorder (import math before from-imports), dropped stray blank lines in import groups, alphabetised+rewrapped convolution/utils from-imports, moved dataset_support import into order. Cat 5: mutable default excludes=[np.nan] in mean() (line 238) -> None sentinel, resolved to [np.nan] in body; never mutated so behaviour preserved; regression test test_mean_default_excludes_does_not_leak added. Cat 1/2 clean. 115 focal tests pass. PR pending."
geotiff,2026-06-14,3329,MEDIUM,4,"Re-sweep after #3259: flake8 baseline 0 across all 33 production files (flake8 7.3.0). Cat 4 only: isort (line_length=100) drift in _writers/eager.py (the from .._validation import block wrapped at ~80 cols, not 100); rewrapped, no behavioural change. Cat 1/2/3/5 clean: no E/W/F codes; grep hits for == False (comment), ': dict'/': list' annotations, and type=getaddrinfo kwarg are all false positives, not shadowed builtins or comparisons. isort+flake8 clean after fix; import smoke test ok. PR via #3329."
hydro-d8,2026-05-29,2705,HIGH,1;3;4,"flake8+isort over the 13 D8 files only (dinf/mfd out of scope). Cat 3 HIGH: F401 x2 (flow_length_d8 function-local _compute_accum_seeds never called; snap_pour_point_d8 module-level cuda_args unused) - both confirmed dead, no re-export. Cat 1: E127/E128 continuation-indent x90 (mostly multi-line def signatures); E302/E303 blank-line cluster in watershed_d8; E501 x4 (flow_path_d8 + snap_pour_point_d8, wrapped ternaries). Cat 4: isort import-block reordering on all 13 files. No Cat 2 (W-codes), no Cat 5 (grep clean: no bare except, mutable defaults, ==None/==True, or shadowed builtins). flake8+isort clean after fix; 385 D8 tests pass. flow_direction_d8 needed manual blank-line placement to satisfy both isort and E302."
Expand Down
21 changes: 9 additions & 12 deletions xrspatial/cost_distance.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
from __future__ import annotations

import math as _math
from functools import partial
from math import sqrt

import numpy as np
Expand All @@ -48,18 +47,16 @@
class cupy: # type: ignore[no-redef]
ndarray = False

from xrspatial.utils import (
_dask_task_name_kwargs,
_validate_raster,
cuda_args, get_dataarray_resolution, ngjit,
has_cuda_and_cupy, is_cupy_array, is_dask_cupy,
)
from xrspatial.dataset_support import supports_dataset
from xrspatial.utils import (_dask_task_name_kwargs, _validate_raster, cuda_args,
get_dataarray_resolution, has_cuda_and_cupy, is_cupy_array,
is_dask_cupy, ngjit)

# ---------------------------------------------------------------------------
# Numba binary min-heap (three parallel arrays: keys, rows, cols)
# ---------------------------------------------------------------------------


@ngjit
def _heap_push(keys, rows, cols, size, key, row, col):
"""Push (key, row, col) onto the heap. Returns new size."""
Expand Down Expand Up @@ -458,8 +455,8 @@ def _cost_distance_cupy(source_data, friction_data, cellsize_x, cellsize_y,


def _cost_distance_dask_cupy(source_da, friction_da,
cellsize_x, cellsize_y, max_cost,
target_values, dy, dx, dd):
cellsize_x, cellsize_y, max_cost,
target_values, dy, dx, dd):
"""Dask+CuPy cost distance.

Bounded max_cost: ``da.map_overlap`` with per-chunk GPU relaxation.
Expand Down Expand Up @@ -1002,9 +999,9 @@ def _process_tile(iy, ix, tile_cache,


def _cost_distance_dask_iterative(source_da, friction_da,
cellsize_x, cellsize_y,
max_cost, target_values,
dy, dx, dd):
cellsize_x, cellsize_y,
max_cost, target_values,
dy, dx, dd):
"""Iterative boundary-only Dijkstra for arbitrarily large dask arrays.

Memory usage is O(sqrt(N)) for inter-iteration storage.
Expand Down
Loading