Tightened automatic continuous screening with a point-to-cell distance bound. Boundary points remain protected by numerical tolerances, without counting entire neighbouring raster cells. Additional feasible trial centres improve the lower bound. Both steps reuse the active portfolio and stored terra cell assignments; the full geometric route and user-supplied thresholds are unchanged.
Accelerated the single-hotspot continuous refinement with a
streaming Rcpp angular sweep. Nearby pair intersections are processed
once over the union of the screened candidate regions, exact
active-portfolio totals are updated at angular events, and only
competitive centres require a confirming indexed radius query. Terra
remains responsible for raster-cell assignment and safe candidate-cell
screening. Optional internal profiling is available through
options(spatialrisk.profile = TRUE) without changing the
standard result.
Made the default continuous screening bounds geometrically consistent. The focal window now spans the radius plus the full raster-cell diagonal, also for non-square cells, and the automatic feasible lower bound is evaluated in the same projected Euclidean coordinates as pair refinement. Added direct tests of the upper bound, feasible lower bound, safe cell pruning, and an optimum at a pair intersection near a raster-cell edge.
Expanded the screening raster in whole-cell steps to cover the portfolio bounding box plus at least the search radius. This retains pair-intersection centres that lie just outside the point extent while preserving the existing raster alignment.
Increased the default max_refinement_points from
1,000 to 1,500. This allows continuous pair-intersection refinement for
moderately larger local candidate sets while retaining grid fallback for
denser searches.
Extended the decomposed hotspot workflow so
optimize_hotspot(prepare_spatialrisk(...)) performs a full
geometric candidate search over the active portfolio, while optimisation
after select_candidates() uses the screened candidate
search state. Candidate generation and scoring are now explicitly
separated: every candidate centre is scored against the complete active
portfolio. The high-level concentration_hotspot() continues
to use the screened continuous search for normal use.
Reused the prepared terra raster-cell membership during continuous refinement. Local candidate points are now retrieved from nearby raster cells, and all candidate regions in one greedy step share a single Rcpp evaluation index instead of rebuilding it for every focal candidate cell. Point pairs shared by overlapping focal candidate regions are processed once for a single hotspot and cached between overlapping regions in the sequential multi-hotspot route. With non-negative values and the default automatic lower bound, exact radius sums are now calculated only for observed or pair-intersection centres whose own terra raster cell passed focal screening. Both centres from a point pair are screened separately. This preserves full-portfolio scoring while substantially reducing the number of exact candidate evaluations.
prepare_spatialrisk(), select_candidates(),
and optimize_hotspot(). These functions expose the
preparation, candidate-selection, and optimisation steps used by
concentration_hotspot(), while keeping
concentration_hotspot() available as the main wrapper for
the complete workflow.concentration_hotspot(method = "continuous")
and optimize_hotspot() so pair-intersection refinement is
evaluated over all focal candidate cells above the lower bound, rather
than only around the top focal cell. Candidate centres are now scored
against the full remaining portfolio before the best hotspot is
selected. This avoids cases where a later n_hotspots
hotspot could have a higher concentration than the first reported
hotspot.n_hotspots > 1 performance for the
continuous hotspot method by caching pair-intersection refinements per
focal candidate cell. After each greedy step, only cache entries
affected by removed contributing points or changed focal cells are
recomputed.n_hotspots hotspot concentrations are non-increasing after
contributing points are removed between iterations.concentration_hotspot() and
optimize_hotspot() now prefer n_hotspots
instead of top_n, and concentration_hotspot()
and select_candidates() now prefer
grid_spacing instead of grid_precision. The
old argument names remain temporarily supported with lifecycle
deprecation warnings.concentration_hotspot() as the main function for
fixed-radius concentration hotspot detection. The function returns a
hotspot object with hotspots and
contributing_points components.method = "continuous" as the default method for
concentration_hotspot(). It searches for hotspot centres
that may lie between observed points, using spatial screening followed
by Rcpp pair-intersection refinement. If the local subset exceeds
max_refinement_points, it falls back to
method = "grid".method = "observed" to
concentration_hotspot(), an experimental Rcpp
spatial-indexing alternative that searches observed point locations
only.find_highest_concentration() in favour of
concentration_hotspot(). The deprecated function remains
available for existing code.concentration() workflow to
radius_sum(), with clearer targets and
reference arguments. The old concentration()
function remains available as a deprecated compatibility wrapper.radius_sum(display_progress = ) to
radius_sum(progress = ) for consistency with
concentration_hotspot().points_in_circle() to
points_within_radius(). The old function remains available
as a deprecated compatibility wrapper.points_to_polygon() with
summarise_points_by_polygon(), which more clearly describes
joining point data to polygons and summarising a numeric point
attribute. The old function remains available as a deprecated
compatibility wrapper.plot_points() to map_points(). The
old function remains available as a deprecated compatibility
wrapper.haversine() and the underlying C++ distance
calculation by reducing unnecessary operations and adding stricter input
checks.points_within_radius() validation and handling
of multiple centre coordinates.radius_sum() validation, output column
handling, and C++ prefiltering of incomplete reference rows.concentration_hotspot() documentation to
clarify that the function uses a grid-based search with local
refinement. The search resolution is controlled by
cell_size and grid_spacing.concentration_hotspot() now uses progress
instead of print_progress. Since this is a new public API,
the old argument is not retained there; older deprecated functions still
translate their legacy progress arguments.interpolate_spline() because spline
interpolation is outside the main scope of the package. The function
remains available for compatibility.choropleth(),
using tmap for both static and interactive output.choropleth_ggplot2() in favour of
choropleth().mapview,
tmap, ggplot2, and classInt to
Suggests.knmi_historic_data() to its own function
documentation file and improved validation for years, station IDs,
progress handling, failed downloads, and temporary-file cleanup.knmi_historic_data() input validation.choropleth() API.DESCRIPTION with a more specific title and
broader package description.find_highest_concentration(): a faster and
more accurate alternative to highest_concentration(),
leveraging focal statistics for optimal results.highest_concentration() in favor of the new,
improved function.plot_points() to utilize
mapview::mapview() for enhanced interactive map
visualizations.plot_points() now returns a warning when a specific
provider tile is not available.neighborhood_gh_search() now returns a more precise
outcome when the radius of the circle is not equal to 200m.sf::st_crs() is used for sf objects to not
show the message that old crs is detected anymore.highest_concentration() now returns correct highest
concentration when the circle of the highest concentration overlaps more
than one geohash.plot.concentration() now handles many lon/lat pairs
better.highest_concentration() is added to do a fast search
for the coordinates of the highest concentration.neighborhood_gh_search() is added to look for even
higher concentrations in the neighborhood of the coordinates found by
highest_concentration().concentration() and points_in_circle() now
return error messages when the data does not contain columns for
lon and lat.concentration() and points_in_circle()
have updated documentation.haversine() now returns NA when coordinates are
missing.points_to_polygon() is updated to keep spatialrisk and
a new version of dplyr working together smoothly.knmi_historic_data() and knmi_stations()
are added to retrieve data from weather stations in the
Netherlands.interpolate_krige() and
interpolate_spline() are added for interpolation and
smoothing on the sphere.nl_corop(), nl_gemeente(),
nl_postcode1(), nl_postcode2(),
nl_postcode3(), nl_postcode4(), and
nl_provincie() now contain columns longitude
and latitude for the centroid of the polygons.areaname in
data set nl_gemeente().choropleth(), n specifies the number of
clusters in a map.nl_corop(), nl_gemeente(),
nl_postcode1(), nl_postcode2(),
nl_postcode3(), nl_postcode4(), and
nl_provincie, column areaname now refers to
the region.points_to_polygon(), outside_print
shows the points that are not within any polygon.points_to_polygon() is added.europe_countries() and
world_countries() are added.concentration() the algorithm for testing if a point
is inside a circle is updated by testing whether the point is inside a
square diamond inside the square.NEWS.md is added to track changes to the package.