From 1d73934c133488fc25955050c900568ed3040463 Mon Sep 17 00:00:00 2001 From: ioes Date: Tue, 20 Oct 2026 22:57:33 +0900 Subject: [PATCH] Advance rounded offshore course at a reached checked onward goal --- src/posim_routing/course.py | 15 ++++++++++++++- tests/test_course.py | 17 +++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/posim_routing/course.py b/src/posim_routing/course.py index cde234c..0abe163 100644 --- a/src/posim_routing/course.py +++ b/src/posim_routing/course.py @@ -62,6 +62,19 @@ def coastal_shape(leg, index, state): def passed_coastal_shape(leg, index, state): points=leg['coordinates'] + if not coastal_shape(leg,index,state): + return False + navigation=(state.get('native') or {}).get('navigation') or {} + # A coastal rounding can reach the following harbour entry without ever + # crossing the incoming plane of the offshore graph vertex. The measured + # arrival at its checked onward goal completes that shape vertex only; + # the following mandatory harbour waypoint retains its own strict radius. + if (rounded_course(leg,index,state) + and navigation.get('route_key')==[state['lap'],state['leg'],index] + and navigation.get('mapped_land_checked') is True + and (state.get('coastal_depth_corridor') or {}).get('accepted') is True + and GEO.inv(*state['position'],*points[index+1])[2]<=50.): + return True # Once a checked coastal path rounds the vertex, moving farther from the # offshore graph point must not make that same point mandatory again. # Passage still requires measured progress through both adjoining planes. @@ -74,7 +87,7 @@ def passed_coastal_shape(leg, index, state): # Its incoming plane would require travelling out to that vertex. Once a # checked coastal rounding is accepted, measured onward passage suffices. require_incoming=not (first_onward and rounded_course(leg,index,state)) - return coastal_shape(leg,index,state) and passed_vertex( + return passed_vertex( points[index-1],points[index],points[index+1],state['position'],maximum_offset=horizon, adjacent_limit=False,require_incoming=require_incoming) diff --git a/tests/test_course.py b/tests/test_course.py index f1630fa..1c4e4db 100644 --- a/tests/test_course.py +++ b/tests/test_course.py @@ -11,6 +11,23 @@ def state(position): coastal_navigation=dict(status='coastal_region')) class CourseTests(unittest.TestCase): + def test_phuket_reached_onward_entry_completes_offshore_shape(self): + leg=dict(coordinates=[[100.6,3.2],[97.,7.], + [98.28911746469352,7.770512146756515], + [98.28994670668614,7.769520412763569]],canal=False, + fixed_approach=dict(policy='fixed-port-waypoints-v1',verified=True,first_waypoint=2)) + sample=state([98.28908548827172,7.770543662774121]) + sample['course_lookahead']=dict(route_key=[0,2,1],target=leg['coordinates'][2],rounded_shape=True) + sample['native']=dict(navigation=dict(route_key=[0,2,1],mapped_land_checked=True)) + sample['coastal_depth_corridor']=dict(accepted=True) + self.assertTrue(passed_coastal_shape(leg,1,sample)) + self.assertFalse(passed_coastal_shape(leg,2,sample),'The harbour entry is still mandatory') + for field in ('course_lookahead','native','coastal_depth_corridor'): + missing=copy.deepcopy(sample);missing.pop(field) + self.assertFalse(passed_coastal_shape(leg,1,missing)) + sample['native']['navigation']['route_key']=[0,1,1] + self.assertFalse(passed_coastal_shape(leg,1,sample)) + def test_distant_offshore_shape_rounds_only_with_checked_matching_onward_goal(self): leg=dict(coordinates=[[109.,16.1],[110.1,12.2],[107.3207,7.6091]],canal=False) sample=state([109.2413,14.4598])