summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBirte Kristina Friesel <derf@finalrewind.org>2024-08-23 22:44:02 +0200
committerBirte Kristina Friesel <derf@finalrewind.org>2024-08-23 22:44:02 +0200
commit520e6456001cf858d7e59606a77b1cf0ab115aa9 (patch)
treeb8fa0927e5ee6e06fc77b791817db89c1ffa8669
parent1a185897e271a9c6471071d8b9b70a5fed16e596 (diff)
Suggest backends based on coverage and latest checkout coordinates
References #156
-rw-r--r--cpanfile1
-rw-r--r--lib/Travelynx/Controller/Account.pm34
-rwxr-xr-xlib/Travelynx/Model/Journeys.pm26
-rw-r--r--templates/select_backend.html.ep39
4 files changed, 100 insertions, 0 deletions
diff --git a/cpanfile b/cpanfile
index f398415..673b738 100644
--- a/cpanfile
+++ b/cpanfile
@@ -7,6 +7,7 @@ requires 'Email::Sender::Simple';
requires 'GIS::Distance';
requires 'GIS::Distance::Fast';
requires 'List::UtilsBy';
+requires 'Math::Polygon';
requires 'MIME::Entity';
requires 'Mojolicious';
requires 'Mojolicious::Plugin::Authentication';
diff --git a/lib/Travelynx/Controller/Account.pm b/lib/Travelynx/Controller/Account.pm
index 1847cda..aa3fa3a 100644
--- a/lib/Travelynx/Controller/Account.pm
+++ b/lib/Travelynx/Controller/Account.pm
@@ -6,6 +6,7 @@ package Travelynx::Controller::Account;
use Mojo::Base 'Mojolicious::Controller';
use JSON;
+use Math::Polygon;
use Mojo::Util qw(xml_escape);
use Text::Markdown;
use UUID::Tiny qw(:std);
@@ -1004,6 +1005,7 @@ sub backend_form {
my $user = $self->current_user;
my @backends = $self->stations->get_backends;
+ my @suggested_backends;
my %place_map = (
AT => 'Österreich',
@@ -1035,6 +1037,10 @@ sub backend_form {
'US-TX' => 'Texas',
);
+ my ( $user_lat, $user_lon )
+ = $self->journeys->get_latest_checkout_latlon( uid => $user->{id} );
+ say $user_lat . ' ' . $user_lon;
+
for my $backend (@backends) {
my $type = 'UNKNOWN';
if ( $backend->{iris} ) {
@@ -1051,6 +1057,33 @@ sub backend_form {
$backend->{regions} = [ map { $place_map{$_} // $_ }
@{ $s->{coverage}{regions} // [] } ];
$backend->{has_area} = $s->{coverage}{area} ? 1 : 0;
+
+ if ( $s->{coverage}{area}
+ and $s->{coverage}{area}{type} eq 'Polygon' )
+ {
+ # [0] == outer polygon, [1:] == holes within polygon
+ my $poly = Math::Polygon->new(
+ @{ $s->{coverage}{area}{coordinates}[0] } );
+ say $backend->{name} . ' ' . $poly->area;
+ if ( $poly->contains( [ $user_lon, $user_lat ] ) ) {
+ push( @suggested_backends, $backend );
+ }
+ }
+ elsif ( $s->{coverage}{area}
+ and $s->{coverage}{area}{type} eq 'MultiPolygon' )
+ {
+ for my $s_poly (
+ @{ $s->{coverage}{area}{coordinates} // [] } )
+ {
+ my $poly
+ = Math::Polygon->new( @{ $s_poly->[0] // [] } );
+ say $backend->{name} . ' ' . $poly->area;
+ if ( $poly->contains( [ $user_lon, $user_lat ] ) ) {
+ push( @suggested_backends, $backend );
+ last;
+ }
+ }
+ }
}
else {
$type = undef;
@@ -1072,6 +1105,7 @@ sub backend_form {
$self->render(
'select_backend',
+ suggestions => \@suggested_backends,
backends => \@backends,
user => $user,
redirect_to => $self->req->param('redirect_to') // '/',
diff --git a/lib/Travelynx/Model/Journeys.pm b/lib/Travelynx/Model/Journeys.pm
index 6d59d44..8a97aef 100755
--- a/lib/Travelynx/Model/Journeys.pm
+++ b/lib/Travelynx/Model/Journeys.pm
@@ -807,6 +807,32 @@ sub get_oldest_ts {
return undef;
}
+sub get_latest_checkout_latlon {
+ my ( $self, %opt ) = @_;
+ my $uid = $opt{uid};
+ my $db = $opt{db} // $self->{pg}->db;
+
+ my $res_h = $db->select(
+ 'journeys_str',
+ [ 'arr_lat', 'arr_lon', ],
+ {
+ user_id => $uid,
+ cancelled => 0
+ },
+ {
+ limit => 1,
+ order_by => { -desc => 'journey_id' }
+ }
+ )->hash;
+
+ if ( not $res_h ) {
+ return;
+ }
+
+ return $res_h->{arr_lat}, $res_h->{arr_lon};
+
+}
+
sub get_latest_checkout_ids {
my ( $self, %opt ) = @_;
my $uid = $opt{uid};
diff --git a/templates/select_backend.html.ep b/templates/select_backend.html.ep
index d5bc9d5..55182f9 100644
--- a/templates/select_backend.html.ep
+++ b/templates/select_backend.html.ep
@@ -14,6 +14,45 @@
% if (stash('redirect_to')) {
%= hidden_field 'redirect_to' => stash('redirect_to')
% }
+ % if (@{stash('suggestions') // []}) {
+ <div class="row">
+ <div class="col s12">
+ <h3>Vorschläge</h3>
+ </div>
+ </div>
+ % for my $backend (@{ stash('suggestions') // [] }) {
+ <div class="row">
+ <div class="col s8 m6 l6 right-align">
+ %= $backend->{longname}
+ % if ($backend->{id} == $user->{backend_id}) {
+ (aktuell ausgewählt)
+ % }
+ % if ($backend->{has_area}) {
+ <br/>
+ <a href="https://dbf.finalrewind.org/coverage/HAFAS/<%= $backend->{name} %>"><%= join(q{, }, @{$backend->{regions} // []}) || '[Karte]' %></a>
+ % }
+ % elsif ($backend->{regions}) {
+ <br/>
+ %= join(q{, }, @{$backend->{regions} // []})
+ % }
+ % if ($backend->{homepage}) {
+ <br/>
+ <a href="<%= $backend->{homepage} %>"><%= $backend->{homepage} =~ s{ ^ http s? :// (?: www[.] )? (.*?) (?: / )? $ }{$1}xr %></a>
+ % }
+ </div>
+ <div class="col s4 m6 l6 left-align">
+ <button class="btn waves-effect waves-light <%= $backend->{id} == $user->{backend_id} ? 'disabled' : q{} %>" style="min-width: 6em;" type="submit" name="backend" value="<%= $backend->{id} %>">
+ <%= $backend->{name} %>
+ </button>
+ </div>
+ </div>
+ % }
+ % }
+ <div class="row">
+ <div class="col s12">
+ <h3>Alle Backends</h3>
+ </div>
+ </div>
% for my $backend (@{ stash('backends') // [] }) {
<div class="row">
<div class="col s8 m6 l6 right-align">