Skip to content
Open
Changes from 7 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
53 changes: 44 additions & 9 deletions libpysal/graph/_triangulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
import pandas
from scipy import sparse, spatial

from libpysal.cg import voronoi_frames

from ..cg import voronoi_frames
from ..weights.util import get_points_array
from ._contiguity import _vertex_set_intersection
from ._kernel import _kernel, _kernel_functions, _optimize_bandwidth
from ._utils import (
Expand Down Expand Up @@ -342,8 +342,7 @@ def _relative_neighborhood(coordinates, coplanar):
return heads_ix, tails_ix, coplanar


@_validate_coplanar
def _voronoi(coordinates, coplanar, clip="bounding_box", rook=True):
def _voronoi(coordinates, ids=None, clip="bounding_box", **kwargs):
"""
Compute contiguity weights according to a clipped
Voronoi diagram.
Expand Down Expand Up @@ -411,21 +410,57 @@ def _voronoi(coordinates, coplanar, clip="bounding_box", rook=True):
delaunay triangulations in many applied contexts and
generally will remove "long" links in the delaunay graph.
"""
coplanar = kwargs.pop("coplanar", "raise")
rook = kwargs.pop("rook", True)
seed = kwargs.pop("seed", None)

for extra in ["decay", "taper", "seed", "bandwidth", "kernel"]:
kwargs.pop(extra, None)

if hasattr(coordinates, "centroid"):
points = numpy.array([[p.x, p.y] for p in coordinates.centroid])
else:
raw_points = get_points_array(coordinates)
points = numpy.array([numpy.array(p) for p in raw_points])

if points.ndim == 1:
points = points.reshape(-1, 2)
elif points.ndim == 3:
points = points.squeeze()

if ids is None:
if hasattr(coordinates, "index"):
ids = coordinates.index.values
else:
ids = numpy.arange(len(points))

if coplanar == "raise":
unique = numpy.unique(coordinates, axis=0)
if unique.shape != coordinates.shape:
unique = numpy.unique(points, axis=0)
if unique.shape[0] != points.shape[0]:
raise CoplanarError(
f"There are {len(unique)} unique locations in "
f"the dataset, but {len(coordinates)} observations. This means there "
f"the dataset, but {len(points)} observations. This means there "
"are multiple points in the same location, which is undefined "
"for this graph type. To address this issue, consider setting "
"`coplanar='clique'` or consult the documentation about "
"coplanar points."
)
cells = voronoi_frames(coordinates, clip=clip, return_input=False, as_gdf=False)

if coplanar == "jitter":
points = _jitter_geoms(points, seed=seed)
kwargs.pop("coplanar", None)

actual_clip = None if clip == "none" or clip is None else clip

cells = voronoi_frames(
points, clip=actual_clip, return_input=False, as_gdf=False, **kwargs
)
heads_ix, tails_ix, weights = _vertex_set_intersection(cells, rook=rook)

return heads_ix, tails_ix, numpy.array([])
final_heads = ids[numpy.array(heads_ix)]
final_tails = ids[numpy.array(tails_ix)]

return final_heads, final_tails, numpy.array(weights)


#### utilities
Expand Down