From 2116da7c6a19860873b5fad4afe6684245f9be4c Mon Sep 17 00:00:00 2001
From: "hieda_kyuko@hpr" <ugo58956@protonmail.com>
Date: Mon, 2 Jun 2025 15:35:30 +0200
Subject: [PATCH] Create metadata frame

---
 lib/App/FrameUtils.pm  | 46 -----------------------------
 lib/App/MasterUtils.pm | 67 ++++++++++++++++++++++++++++++++++++++++++
 lib/App/Navi.pm        |  2 +-
 src/oud2_parser.pl     |  8 +++--
 4 files changed, 73 insertions(+), 50 deletions(-)

diff --git a/lib/App/FrameUtils.pm b/lib/App/FrameUtils.pm
index 2656681..5026e68 100644
--- a/lib/App/FrameUtils.pm
+++ b/lib/App/FrameUtils.pm
@@ -39,52 +39,6 @@ sub get_destination
 	->{'ekimei'};
 }
 
-sub get_patterns_at_sta
-{
-    my ($master, $rosen_id, $eki) = @_;
-    my $rosen = MasterUtils::get_rosen_frame $master, $rosen_id;
-    my $pos_down = MasterUtils::get_eki_position $master, $rosen_id, $eki;
-    my $pos_up = $rosen->{'eki_num'} - $pos_down - 1;
-    my @services_down = @{ $rosen->{'dia'}->{'kudari'} };
-    my @services_up = @{ $rosen->{'dia'}->{'nobori'} };
-    my %stopping_patterns;
-
-    foreach my $ressya (@services_down)
-    {
-	my @jikoku = @{ $ressya->{'jikoku'} };
-	my $pos = 0;
-	while ($pos != $pos_down) { shift @jikoku; $pos++; }
-	if (!defined $jikoku[0]) { next; }
-	
-	my $ts = $jikoku[0];
-	my $time = $ts->{'hatsu'};
-	# Timestamp has no dep time (only arrival time for ex)
-	if (!defined $time) { next; }
-	# This service does not stop here
-	if ($ts->{'mode'} != 1) { next; }
-
-	$stopping_patterns{$ressya->{'syubetsu'}}++;
-    }
-    foreach my $ressya (@services_up)
-    {
-	my @jikoku = @{ $ressya->{'jikoku'} };
-	my $pos = 0;
-	while ($pos != $pos_up) { shift @jikoku; $pos++; }
-	if (!defined $jikoku[0]) { next; }
-	
-	my $ts = $jikoku[0];
-	my $time = $ts->{'hatsu'};
-	# Timestamp has no dep time (only arrival time for ex)
-	if (!defined $time) { next; }
-	# This service does not stop here
-	if ($ts->{'mode'} != 1) { next; }
-
-	$stopping_patterns{$ressya->{'syubetsu'}}++;
-    }
-
-    return scalar keys %stopping_patterns;
-}
-
 sub hassya_hyou
 {
     my $master = $_[0];
diff --git a/lib/App/MasterUtils.pm b/lib/App/MasterUtils.pm
index 6fc00e2..4ba65ee 100644
--- a/lib/App/MasterUtils.pm
+++ b/lib/App/MasterUtils.pm
@@ -141,4 +141,71 @@ sub get_routes
     @res ? return @res : Log::e "$id has no routes";
 }
 
+sub get_patterns_at_sta
+{
+    my ($master, $rosen_id, $eki) = @_;
+    my $rosen = get_rosen_frame $master, $rosen_id;
+    my $pos_down = get_eki_position $master, $rosen_id, $eki;
+    my $pos_up = $rosen->{'eki_num'} - $pos_down - 1;
+    my @services_down = @{ $rosen->{'dia'}->{'kudari'} };
+    my @services_up = @{ $rosen->{'dia'}->{'nobori'} };
+    my %stopping_patterns;
+
+    foreach my $ressya (@services_down)
+    {
+	my @jikoku = @{ $ressya->{'jikoku'} };
+	my $pos = 0;
+	while ($pos != $pos_down) { shift @jikoku; $pos++; }
+	if (!defined $jikoku[0]) { next; }
+	
+	my $ts = $jikoku[0];
+	my $time = $ts->{'hatsu'};
+	# Timestamp has no dep time (only arrival time for ex)
+	if (!defined $time) { next; }
+	# This service does not stop here
+	if ($ts->{'mode'} != 1) { next; }
+
+	$stopping_patterns{$ressya->{'syubetsu'}}++;
+    }
+    foreach my $ressya (@services_up)
+    {
+	my @jikoku = @{ $ressya->{'jikoku'} };
+	my $pos = 0;
+	while ($pos != $pos_up) { shift @jikoku; $pos++; }
+	if (!defined $jikoku[0]) { next; }
+	
+	my $ts = $jikoku[0];
+	my $time = $ts->{'hatsu'};
+	# Timestamp has no dep time (only arrival time for ex)
+	if (!defined $time) { next; }
+	# This service does not stop here
+	if ($ts->{'mode'} != 1) { next; }
+
+	$stopping_patterns{$ressya->{'syubetsu'}}++;
+    }
+
+    return scalar keys %stopping_patterns;
+}
+
+sub build_metadata
+{
+    my ($master) = @_;
+    my $metadata = {};
+    foreach my $rosen (keys %{ $master->{'rosen'} })
+    {
+	my $frame = {};
+
+	# Add number of stopping patterns for each station / route
+	my $patterns = {};
+	foreach my $eki (@{ $master->{'rosen'}->{$rosen}->{'eki'} })
+	{
+	    $patterns->{$eki} = get_patterns_at_sta $master, $rosen, $eki;
+	}
+	$frame->{'stopping_patterns'} = $patterns;
+	
+	$metadata->{$rosen} = $frame;
+    }
+    $master->{'metadata'} = $metadata;
+}
+
 1;
diff --git a/lib/App/Navi.pm b/lib/App/Navi.pm
index 92e9bb4..b6455f5 100644
--- a/lib/App/Navi.pm
+++ b/lib/App/Navi.pm
@@ -194,7 +194,7 @@ sub Raptor_simple
 			# This will most likely save a lot of time on routes with a great amount of stops / services (e.g. high-frequency lines)
 			my $all_patterns = MasterUtils::get_patterns $master, $r;
 			# TODO maybe move these computations to a "metadata" frame
-			my $stopping_patterns = FrameUtils::get_patterns_at_sta $master, $r, $pi;
+			my $stopping_patterns = $master->{'metadata'}->{$r}->{$pi};
 			if ($stopping_patterns < 2 && $all_patterns >= 3)
 			{
 			    $mark = 0;
diff --git a/src/oud2_parser.pl b/src/oud2_parser.pl
index eefe008..867daff 100644
--- a/src/oud2_parser.pl
+++ b/src/oud2_parser.pl
@@ -416,6 +416,8 @@ foreach my $frame (values %{ $master{'rosen'} })
     $frame->{'eki'} = \@new_ekis;
 }
 
+MasterUtils::build_metadata \%master;
+
 # Parse transfer times
 my $recce = Marpa::R2::Scanless::R->new(
     {
@@ -449,11 +451,11 @@ $master{'transfer_times'} = $transfers;
 
 # FrameUtils::hassya_hyou \%master, 'sekihoku1_28';
 
-my $d = MasterUtils::search_eki \%master, '石北大通';
-my $a = MasterUtils::search_eki \%master, '一区下';
+my $d = MasterUtils::search_eki \%master, '帯広';
+my $a = MasterUtils::search_eki \%master, '釧路';
 
 sub eki { return MasterUtils::search_eki \%master, $_[0]; }
 
-Navi::Raptor_simple \%master, $d, $a, 1120;
+Navi::Raptor_simple \%master, $d, $a, 525;
 
 # FrameUtils::hassya_hyou \%master, (eki '古瀬');
-- 
GitLab