diff options
| author | Birte Kristina Friesel <birte.friesel@uos.de> | 2024-08-24 07:59:19 +0200 | 
|---|---|---|
| committer | Birte Kristina Friesel <birte.friesel@uos.de> | 2024-08-24 07:59:19 +0200 | 
| commit | c142d4fae4ba69d81437f74f5152f9a3232da926 (patch) | |
| tree | 469afb5b20f5e6bdada8107b06438d072f44c687 | |
| parent | 087536862b26619fbf63423d15469d46d70f2365 (diff) | |
backend suggestions: handle holes in GeoJSON polygons
| -rw-r--r-- | lib/Travelynx/Controller/Account.pm | 48 | 
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;  						} | 
