hit method
InteractivePolyline<Object> ?
hit(
- List<
InteractivePolyline< polylines,Object> > - Offset p, {
- Key? preferKey,
Returns the index of the hit polyline, or null.
preferKey (active/hover) is tested first to feel "sticky" when overlapping.
Implementation
InteractivePolyline? hit(
List<InteractivePolyline> polylines,
Offset p, {
Key? preferKey,
}) {
if (polylines.isEmpty) return null;
// 1. Prepare candidates from Index
Set<Key>? candidateKeys;
if (index != null) {
// Create a search bounds around the touch point based on tolerance
final bounds = _createHitBounds(p, hitTolerance + 2.0); // +2 safety
candidateKeys =
index!.query(bounds).map((pl) => pl.key).whereType<Key>().toSet();
if (candidateKeys.isEmpty) return null;
}
Iterable<int> order() sync* {
if (preferKey != null) {
final prefIdx = _indexOfKeyOrNull(polylines, preferKey);
if (prefIdx != null) yield prefIdx;
}
for (int i = polylines.length - 1; i >= 0; i--) {
if (preferKey != null && polylines[i].key == preferKey) continue;
yield i; // top-most first
}
}
double minDst = double.infinity;
InteractivePolyline? bestHit;
for (final i in order()) {
final polyline = polylines[i];
if (candidateKeys != null && !candidateKeys.contains(polyline.key)) {
continue;
}
final points = polyline.points;
// Optimization: Simple bbox check (redundant if using index, but cheap)
// if (index == null && !polyline.bounds.contains(pointLatLng)) continue; // TODO: polyline.bounds?
// Determine hit based on segments
final offsets = points.map(cam.latLngToScreenOffset).toList();
for (int j = 0; j < offsets.length - 1; j++) {
final d = math_utils.distToSegment(p, offsets[j], offsets[j + 1]);
if (d < hitTolerance && d < minDst) {
minDst = d;
bestHit = polyline;
// Optimization: If we are very close to the line, assume direct hit.
if (d < 0.5) {
return polyline;
}
if (preferKey != null && polyline.key == preferKey) {
return polyline;
}
}
}
}
return bestHit;
}