"Fossies" - the Fresh Open Source Software Archive

Member "pandora_server/lib/PandoraFMS/GIS.pm" (15 Sep 2021, 6901 Bytes) of package /linux/misc/pandorafms_server-7.0NG.757.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Perl source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "GIS.pm" see the Fossies "Dox" file reference documentation.

    1 package PandoraFMS::GIS;
    2 ##########################################################################
    3 # GIS Pandora FMS functions.
    4 # Pandora FMS. the Flexible Monitoring System. http://www.pandorafms.org
    5 ##########################################################################
    6 # Copyright (c) 2005-2021 Artica Soluciones Tecnologicas S.L
    7 #
    8 # This program is free software; you can redistribute it and/or
    9 # modify it under the terms of the GNU Lesser General Public License
   10 # as published by the Free Software Foundation; version 2
   11 # This program is distributed in the hope that it will be useful,
   12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
   13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14 # GNU General Public License for more details.
   15 # You should have received a copy of the GNU General Public License
   16 # along with this program; if not, write to the Free Software
   17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   18 ##########################################################################
   19 
   20 =head1 NAME 
   21 
   22 PandoraFMS::GIS - Geographic Information System functions of Pandora FMS
   23 
   24 =head1 VERSION
   25 
   26 Version 3.1
   27 
   28 =head1 SYNOPSIS
   29 
   30  use PandoraFMS::GIS;
   31 
   32 =head1 DESCRIPTION
   33 
   34 This module contains the B<GIS> (Geographic Information System) related  functions of B<Pandora FMS>
   35 
   36 =head2 Interface
   37 Exported Functions:
   38 
   39 =over
   40 
   41 =item * C<distance_moved>
   42 
   43 =item * C<get_geoip_info>
   44 
   45 =back
   46 
   47 =head1 METHODS
   48 
   49 =cut
   50 
   51 use strict;
   52 use warnings;
   53 use Geo::IP;
   54 
   55 # Default lib dir for RPM and DEB packages
   56 use lib '/usr/lib/perl5';
   57 
   58 use PandoraFMS::DB;
   59 use PandoraFMS::Tools;
   60 
   61 
   62 require Exporter;
   63 
   64 our @ISA = ("Exporter");
   65 our %EXPORT_TAGS = ( 'all' => [ qw( ) ] );
   66 our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
   67 our @EXPORT = qw(   
   68     distance_moved
   69     get_geoip_info
   70     );
   71 # Some intenrnal constants
   72 
   73 my $earth_radius_in_meters = 6372797.560856;
   74 my $pi =  4*atan2(1,1);
   75 my $to_radians= $pi/180;
   76 my $to_half_radians= $pi/360;
   77 my $to_degrees = 180/$pi;
   78 
   79 ##########################################################################
   80 =head2 C<< distance_moved (I<$pa_config>, I<$last_longitude>, I<$last_latitude>, I<$last_altitude>, I<$longitude>, I<$latitude>, I<$altitude>) >> 
   81 
   82 Measures the distance between the last position and the previous one taking in acount the earth curvature
   83 The distance is based on Havesine formula and so far doesn't take on account the altitude
   84 
   85 B<< Refferences (I<Theory>): >>
   86  * L<http://franchu.net/2007/11/16/gis-calculo-de-distancias-sobre-la-tierra/>
   87  * L<http://en.wikipedia.org/wiki/Haversine_formula>
   88 
   89 B<< References (I<C implementation>): >>
   90  * L<http://blog.julien.cayzac.name/2008/10/arc-and-distance-between-two-points-on.html>
   91 
   92 =cut
   93 ##########################################################################
   94 sub distance_moved ($$$$$$$) {
   95     my ($pa_config, $last_longitude, $last_latitude, $last_altitude,
   96         $longitude, $latitude, $altitude) = @_;
   97     
   98     if (!is_numeric($last_longitude) &&
   99         !is_numeric($longitude) &&
  100         !is_numeric($last_latitude) &&
  101         !is_numeric($latitude)) {
  102         return 0;
  103     }
  104     
  105     my $long_difference = $last_longitude - $longitude;
  106     my $lat_difference = $last_latitude - $latitude;
  107     #my $alt_difference = $last_altitude - $altitude;
  108     
  109     
  110     my $long_aux = sin ($long_difference * $to_half_radians);
  111     my $lat_aux = sin ($lat_difference * $to_half_radians);
  112     $long_aux *= $long_aux;
  113     $lat_aux *= $lat_aux;
  114     # Temporary value to make sorter the asin formula.
  115     my $asinaux = sqrt($lat_aux +
  116         cos($last_latitude*$to_radians) * cos($latitude * $to_radians) * $long_aux );
  117     # Assure the aux value is not greater than 1 
  118     if ($asinaux > 1) {
  119         $asinaux = 1;
  120     }
  121     # We use: asin(x)  = atan2(x, sqrt(1-x*x))
  122     my $dist_in_rad = 2.0 * atan2($asinaux, sqrt (1 - $asinaux * $asinaux));
  123     my $dist_in_meters = $earth_radius_in_meters * $dist_in_rad;
  124     
  125     logger($pa_config,
  126         "Distance moved:" . $dist_in_meters ." meters", 10);
  127     
  128     return $dist_in_meters;
  129 }
  130 
  131 ##########################################################################
  132 =head2 C<< get_geoip_info (I<$pa_config>, I<$address>, I<$dispersion>) >>
  133 
  134 Get GIS information from the MaxMind GeoIP database on file using Geo::IP module
  135 
  136 B<Returns>: I<undef> if there is not information available or a B<hash ref> with:
  137  * I<longitude>
  138  * I<latitude>
  139 
  140 =cut
  141 ##########################################################################
  142 sub get_geoip_info {
  143     my ($pa_config, $address) = @_;
  144 
  145     # Return undef if feature is not activated
  146     return undef unless ($pa_config->{'activate_gis'} && $pa_config->{'recon_reverse_geolocation_file'} ne '');
  147 
  148     my $record = undef;
  149     eval {
  150         local $SIG{__DIE__};
  151         my $gi = Geo::IP->open($pa_config->{'recon_reverse_geolocation_file'}, GEOIP_STANDARD);
  152         die("Cannot load the geoip file \"" . $pa_config->{'recon_reverse_geolocation_file'} . "\".\n") unless defined($gi);
  153         $record = $gi->record_by_addr($address);
  154     };
  155     if ($@) {
  156         logger($pa_config, "Error giving coordinates to IP: $address. $@", 8);
  157     }
  158     return undef unless defined($record);
  159 
  160     # Fuzzy position filter
  161     my ($longitude, $latitude) = get_random_close_point (
  162         $pa_config, $record->longitude, $record->latitude
  163     );
  164 
  165     return {
  166         "longitude" => $longitude,
  167         "latitude" => $latitude
  168     };
  169 }
  170 
  171 ##########################################################################
  172 =head2 C<< get_random_close_point(I<$pa_config>, I<$center_longitude>, I<$center_latitude>) >> 
  173 
  174 Gets the B<Longitude> and the B<Laitiutde> of a random point in the surroundings of the 
  175 coordintaes received (I<$center_longitude>, I<$center_latitude>).
  176 
  177 Returns C<< (I<$longitude>, I<$laitiutde>) >>
  178 =cut
  179 ##########################################################################
  180 sub get_random_close_point ($$$) {
  181     my ($pa_config, $center_longitude, $center_latitude) = @_;
  182 
  183     return ($center_longitude, $center_latitude) if ($pa_config->{'recon_location_scatter_radius'} == 0);
  184 
  185     my $sign = int rand(2);
  186     my $longitude = ($sign*(-1)+(1-$sign)) * rand($pa_config->{'recon_location_scatter_radius'}/$earth_radius_in_meters)*$to_degrees;
  187     logger($pa_config,"Longitude random offset '$longitude' ", 8);
  188     $longitude += $center_longitude;
  189     logger($pa_config,"Longitude with random offset '$longitude' ", 8);
  190     $sign = int rand(2);
  191     my $latitude = ($sign*(-1)+(1-$sign)) * rand($pa_config->{'recon_location_scatter_radius'}/$earth_radius_in_meters)*$to_degrees;
  192     logger($pa_config,"Longitude random offset '$latitude' ", 8);
  193     $latitude += $center_latitude;
  194     logger($pa_config,"Latiitude with random offset '$latitude' ", 8);
  195     return ($longitude, $latitude);
  196 }
  197 
  198 # End of function declaration
  199 # End of defined Code
  200 
  201 1;
  202 __END__
  203 
  204 =head1 DEPENDENCIES
  205 
  206 L<PandoraFMS::DB>, L<PandoraFMS::Tools>, L<Geo::IP>
  207 
  208 =head1 LICENSE
  209 
  210 This is released under the GNU Lesser General Public License.
  211 
  212 =head1 SEE ALSO
  213 
  214 L<PandoraFMS::DB>, L<PandoraFMS::Tools>
  215 
  216 =head1 COPYRIGHT
  217 
  218 Copyright (c) 2005-2021 Artica Soluciones Tecnologicas S.L
  219 
  220 =cut