Skip to content

Commit d5fa174

Browse files
committed
FIX: add extra condition on seam splitting
1 parent 9b23857 commit d5fa174

4 files changed

Lines changed: 29 additions & 15 deletions

File tree

-5.01 KB
Loading
-18.7 KB
Loading
-2.32 KB
Loading

lib/cartopy/trace.pyx

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -605,9 +605,21 @@ cdef void _resample_recursive(
605605
# O(2^depth) calls for points outside the domain.
606606
return
607607

608-
# Check for a wrap-around: midpoint outside segment's [0,1] along-range
609-
# means the geodesic crosses the domain boundary (e.g. antimeridian)
610-
# without a state change.
608+
# Check for a coordinate wrap-around at a projection seam (e.g., the
609+
# antimeridian in PlateCarree). When p_mid falls outside the [0,1]
610+
# along-range of the chord from p_start to p_end, one of two things has
611+
# happened:
612+
#
613+
# (1) Genuine seam: the projected path crosses a coordinate-space
614+
# discontinuity (longitude jumps from +180 to -180).
615+
# _find_valid_boundary will return p_in and p_out that are nearly
616+
# identical in parameter space (t) but far apart in coordinate space (p).
617+
#
618+
# (2) High projection curvature: the path bends so sharply that the
619+
# midpoint of a straight chord misrepresents the actual arc, but
620+
# there is no coordinate discontinuity. _find_valid_boundary
621+
# converges to a tiny parameter interval, giving p_in and p_out
622+
# only ~threshold apart in coordinate space.
611623
seg_dx_w = p_end.x - p_start.x
612624
seg_dy_w = p_end.y - p_start.y
613625
seg_hq_w = seg_dx_w*seg_dx_w + seg_dy_w*seg_dy_w
@@ -616,24 +628,26 @@ cdef void _resample_recursive(
616628
mid_dy_w = p_mid.y - p_start.y
617629
along_w = (seg_dx_w*mid_dx_w + seg_dy_w*mid_dy_w) / seg_hq_w
618630
if along_w < 0.0 or along_w > 1.0:
619-
# Wrap: find the boundary, split, and recurse each side.
620631
_find_valid_boundary(t_start, p_start, t_end, p_end,
621632
interpolator, domain, threshold,
622633
&t_in, &p_in, &t_out, &p_out,
623634
geom_fully_inside)
624-
if t_in > t_start + 1e-6:
625-
_resample_recursive(t_start, p_start, state_start,
626-
t_in, p_in,
635+
if (p_out.x - p_in.x)**2 + (p_out.y - p_in.y)**2 > (threshold * 50.0)**2:
636+
# far apart coordinates indicating a seam/antimeridian, split the line here.
637+
if t_in > t_start + 1e-6:
638+
_resample_recursive(t_start, p_start, state_start,
639+
t_in, p_in,
640+
interpolator, domain, threshold,
641+
lines, depth - 1, geom_fully_inside)
642+
else:
643+
lines.add_point_if_empty(p_start)
644+
lines.new_line()
645+
_resample_recursive(t_out, p_out, state_start,
646+
t_end, p_end,
627647
interpolator, domain, threshold,
628648
lines, depth - 1, geom_fully_inside)
629-
else:
630-
lines.add_point_if_empty(p_start)
631-
lines.new_line()
632-
_resample_recursive(t_out, p_out, state_start,
633-
t_end, p_end,
634-
interpolator, domain, threshold,
635-
lines, depth - 1, geom_fully_inside)
636-
return
649+
return
650+
# else: similar projected coordinates, no break needed
637651

638652
# Normal curvature subdivision.
639653
_resample_recursive(t_start, p_start, state_start, t_mid, p_mid,

0 commit comments

Comments
 (0)