summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBirte Kristina Friesel <birte.friesel@uos.de>2024-08-24 07:59:19 +0200
committerBirte Kristina Friesel <birte.friesel@uos.de>2024-08-24 07:59:19 +0200
commitc142d4fae4ba69d81437f74f5152f9a3232da926 (patch)
tree469afb5b20f5e6bdada8107b06438d072f44c687
parent087536862b26619fbf63423d15469d46d70f2365 (diff)
backend suggestions: handle holes in GeoJSON polygons
-rw-r--r--lib/Travelynx/Controller/Account.pm48
1 files changed, 34 insertions, 14 deletions
diff --git a/lib/Travelynx/Controller/Account.pm b/lib/Travelynx/Controller/Account.pm
index aa3fa3a..46e44d1 100644
--- a/lib/Travelynx/Controller/Account.pm
+++ b/lib/Travelynx/Controller/Account.pm
@@ -1000,6 +1000,25 @@ sub password_form {
$self->render('change_password');
}
+sub lonlat_in_polygon {
+ my ( $self, $polygon, $lonlat ) = @_;
+
+ my $circle = shift( @{$polygon} );
+ my @holes = @{$polygon};
+
+ my $circle_poly = Math::Polygon->new( @{$circle} );
+ if ( $circle_poly->contains($lonlat) ) {
+ for my $hole (@holes) {
+ my $hole_poly = Math::Polygon->new( @{$hole} );
+ if ( $hole_poly->contains($lonlat) ) {
+ return;
+ }
+ }
+ return 1;
+ }
+ return;
+}
+
sub backend_form {
my ($self) = @_;
my $user = $self->current_user;
@@ -1039,7 +1058,6 @@ sub backend_form {
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';
@@ -1058,16 +1076,16 @@ sub backend_form {
@{ $s->{coverage}{regions} // [] } ];
$backend->{has_area} = $s->{coverage}{area} ? 1 : 0;
- if ( $s->{coverage}{area}
- and $s->{coverage}{area}{type} eq 'Polygon' )
+ if (
+ $s->{coverage}{area}
+ and $s->{coverage}{area}{type} eq 'Polygon'
+ and $self->lonlat_in_polygon(
+ $s->{coverage}{area}{coordinates},
+ [ $user_lon, $user_lat ]
+ )
+ )
{
- # [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 );
- }
+ push( @suggested_backends, $backend );
}
elsif ( $s->{coverage}{area}
and $s->{coverage}{area}{type} eq 'MultiPolygon' )
@@ -1075,10 +1093,12 @@ sub backend_form {
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 ] ) ) {
+ if (
+ $self->lonlat_in_polygon(
+ $s_poly, [ $user_lon, $user_lat ]
+ )
+ )
+ {
push( @suggested_backends, $backend );
last;
}