2020-02-18 09:49:27 +00:00
< ? php
if ( ! defined ( 'BASEPATH' )) exit ( 'No direct script access allowed' );
class Distances_model extends CI_Model
{
function __construct ()
{
// Call the Model constructor
parent :: __construct ();
}
2021-01-30 22:25:13 +00:00
public $bandslots = array ( " 160m " => 0 ,
" 80m " => 0 ,
" 60m " => 0 ,
" 40m " => 0 ,
" 30m " => 0 ,
" 20m " => 0 ,
" 17m " => 0 ,
" 15m " => 0 ,
" 12m " => 0 ,
" 10m " => 0 ,
" 6m " => 0 ,
" 4m " => 0 ,
" 2m " => 0 ,
" 70cm " => 0 ,
" 23cm " => 0 ,
" 13cm " => 0 ,
" 9cm " => 0 ,
" 6cm " => 0 ,
" 3cm " => 0 ,
" 1.25cm " => 0 );
function get_worked_sats () {
2021-09-12 14:46:16 +00:00
$CI =& get_instance ();
$CI -> load -> model ( 'logbooks_model' );
$logbooks_locations_array = $CI -> logbooks_model -> list_logbook_relationships ( $this -> session -> userdata ( 'active_station_logbook' ));
$location_list = " ' " . implode ( " ',' " , $logbooks_locations_array ) . " ' " ;
2021-01-30 22:25:13 +00:00
// get all worked sats from database
2021-09-12 14:46:16 +00:00
$sql = " SELECT distinct col_sat_name FROM " . $this -> config -> item ( 'table_name' ) . " WHERE station_id in ( " . $location_list . " ) and coalesce(col_sat_name, '') <> '' ORDER BY col_sat_name " ;
2021-01-30 22:25:13 +00:00
$data = $this -> db -> query ( $sql );
$worked_sats = array ();
foreach ( $data -> result () as $row ){
array_push ( $worked_sats , $row -> col_sat_name );
}
return $worked_sats ;
}
function get_worked_bands () {
2021-09-12 14:46:16 +00:00
$CI =& get_instance ();
$CI -> load -> model ( 'logbooks_model' );
$logbooks_locations_array = $CI -> logbooks_model -> list_logbook_relationships ( $this -> session -> userdata ( 'active_station_logbook' ));
$location_list = " ' " . implode ( " ',' " , $logbooks_locations_array ) . " ' " ;
2021-01-30 22:25:13 +00:00
// get all worked slots from database
2021-09-12 14:46:16 +00:00
$sql = " SELECT distinct LOWER(COL_BAND) as COL_BAND FROM " . $this -> config -> item ( 'table_name' ) . " WHERE station_id in ( " . $location_list . " ) " ;
2021-01-30 22:25:13 +00:00
$data = $this -> db -> query ( $sql );
$worked_slots = array ();
foreach ( $data -> result () as $row ){
array_push ( $worked_slots , $row -> COL_BAND );
}
// bring worked-slots in order of defined $bandslots
$results = array ();
foreach ( array_keys ( $this -> bandslots ) as $slot ) {
if ( in_array ( $slot , $worked_slots )) {
array_push ( $results , $slot );
}
}
return $results ;
}
2020-11-20 10:55:55 +00:00
function get_distances ( $postdata , $measurement_base )
2020-02-18 09:49:27 +00:00
{
2021-09-12 14:46:16 +00:00
$CI =& get_instance ();
$CI -> load -> model ( 'logbooks_model' );
$logbooks_locations_array = $CI -> logbooks_model -> list_logbook_relationships ( $this -> session -> userdata ( 'active_station_logbook' ));
$result = array ();
foreach ( $logbooks_locations_array as $station_id ) {
$station_gridsquare = $this -> find_gridsquare ( $station_id );
if ( $station_gridsquare != " " ) {
$gridsquare = explode ( ',' , $station_gridsquare ); // We need to convert to an array, since a user can enter several gridsquares
$this -> db -> select ( 'col_call callsign, col_gridsquare grid' );
$this -> db -> where ( 'LENGTH(col_gridsquare) >' , 0 );
if ( $postdata [ 'band' ] == 'sat' ) {
$this -> db -> where ( 'col_prop_mode' , $postdata [ 'band' ]);
if ( $postdata [ 'sat' ] != 'All' ) {
$this -> db -> where ( 'col_sat_name' , $postdata [ 'sat' ]);
}
}
else {
$this -> db -> where ( 'col_band' , $postdata [ 'band' ]);
}
$this -> db -> where ( 'station_id' , $station_id );
$dataarrayata = $this -> db -> get ( $this -> config -> item ( 'table_name' ));
$temp = $this -> plot ( $dataarrayata -> result_array (), $gridsquare , $measurement_base );
$result = $this -> mergeresult ( $result , $temp );
}
}
if ( $result ) {
header ( 'Content-Type: application/json' );
echo json_encode ( $result );
}
else {
header ( 'Content-Type: application/json' );
echo json_encode ( array ( 'Error' => 'No QSOs found to plot.' ));
}
2020-02-18 09:49:27 +00:00
}
2021-09-12 14:46:16 +00:00
/*
* We merge the result from several station_id ' s . They can have different gridsquares , so we need to use the correct gridsquare to calculate the correct distance .
*/
function mergeresult ( $result , $add ) {
if ( sizeof ( $result ) > 0 ) {
if ( $result [ 'qrb' ][ 'Distance' ] < $add [ 'qrb' ][ 'Distance' ]) {
$result [ 'qrb' ][ 'Distance' ] = $add [ 'qrb' ][ 'Distance' ];
$result [ 'qrb' ][ 'Grid' ] = $add [ 'qrb' ][ 'Grid' ];
$result [ 'qrb' ][ 'Callsign' ] = $add [ 'qrb' ][ 'Callsign' ];
}
$result [ 'qrb' ][ 'Qsos' ] += $add [ 'qrb' ][ 'Qsos' ];
for ( $i = 0 ; $i <= 399 ; $i ++ ) {
$result [ 'qsodata' ][ $i ][ 'count' ] += $add [ 'qsodata' ][ $i ][ 'count' ];
if ( $result [ 'qsodata' ][ $i ][ 'callcount' ] < 5 && $add [ 'qsodata' ][ $i ][ 'callcount' ] > 0 ) {
$calls = explode ( ',' , $add [ 'qsodata' ][ $i ][ 'calls' ]);
foreach ( $calls as $c ) {
if ( $result [ 'qsodata' ][ $i ][ 'callcount' ] < 5 ) {
if ( $result [ 'qsodata' ][ $i ][ 'callcount' ] > 0 ) {
$result [ 'qsodata' ][ $i ][ 'calls' ] .= ', ' ;
}
$result [ 'qsodata' ][ $i ][ 'calls' ] .= $c ;
$result [ 'qsodata' ][ $i ][ 'callcount' ] ++ ;
}
}
}
}
return $result ;
}
return $add ;
}
/*
* Fetches the gridsquare from the station_id
*/
function find_gridsquare ( $station_id ) {
$this -> db -> where ( 'station_id' , $station_id );
return $this -> db -> get ( 'station_profile' ) -> row () -> station_gridsquare ;
}
2020-02-18 09:49:27 +00:00
// This functions takes query result from the database and extracts grids from the qso,
// then calculates distance between homelocator and locator given in qso.
// It builds an array, which has 50km intervals, then inputs each length into the correct spot
// The function returns a json-encoded array.
2020-11-20 10:55:55 +00:00
function plot ( $qsoArray , $gridsquare , $measurement_base ) {
2020-02-18 09:49:27 +00:00
$stationgrid = strtoupper ( $gridsquare [ 0 ]); // We use only the first entered gridsquare from the active profile
if ( strlen ( $stationgrid ) == 4 ) $stationgrid .= 'MM' ; // adding center of grid if only 4 digits are specified
2020-11-20 10:55:55 +00:00
switch ( $measurement_base ) {
case 'M' :
$unit = " mi " ;
$dist = '13000' ;
break ;
case 'K' :
$unit = " km " ;
$dist = '20000' ;
break ;
case 'N' :
$unit = " nmi " ;
$dist = '11000' ;
break ;
2020-11-20 11:14:30 +00:00
default :
$unit = " km " ;
$dist = '20000' ;
2020-11-20 10:55:55 +00:00
}
2020-02-18 09:49:27 +00:00
if ( ! $this -> valid_locator ( $stationgrid )) {
header ( 'Content-Type: application/json' );
echo json_encode ( array ( 'Error' => 'Error. There is a problem with the gridsquare set in your profile!' ));
}
else {
// Making the array we will use for plotting, we save occurrences of the length of each qso in the array
$j = 0 ;
2020-11-20 10:55:55 +00:00
for ( $i = 0 ; $j < $dist ; $i ++ ) {
$dataarray [ $i ][ 'dist' ] = $j . $unit . ' - ' . ( $j + 50 ) . $unit ;
2020-02-18 09:49:27 +00:00
$dataarray [ $i ][ 'count' ] = 0 ;
$dataarray [ $i ][ 'calls' ] = '' ;
$dataarray [ $i ][ 'callcount' ] = 0 ;
$j += 50 ;
}
2021-09-12 14:46:16 +00:00
2020-02-18 09:49:27 +00:00
$qrb = array ( // Used for storing the QSO with the longest QRB
'Callsign' => '' ,
'Grid' => '' ,
'Distance' => '' ,
2021-09-12 14:46:16 +00:00
'Qsos' => '' ,
2020-02-18 09:49:27 +00:00
'Grids' => ''
);
2021-09-12 14:46:16 +00:00
2020-02-18 09:49:27 +00:00
foreach ( $qsoArray as $qso ) {
2021-09-12 14:46:16 +00:00
$qrb [ 'Qsos' ] ++ ; // Counts up number of qsos
2020-11-20 10:55:55 +00:00
$bearingdistance = $this -> bearing_dist ( $stationgrid , $qso [ 'grid' ], $measurement_base ); // Calculates distance based on grids
2020-02-18 09:49:27 +00:00
$arrayplacement = $bearingdistance / 50 ; // Resolution is 50, calculates where to put result in array
if ( $bearingdistance > $qrb [ 'Distance' ]) { // Saves the longest QSO
$qrb [ 'Distance' ] = $bearingdistance ;
$qrb [ 'Callsign' ] = $qso [ 'callsign' ];
$qrb [ 'Grid' ] = $qso [ 'grid' ];
}
2021-09-12 14:46:16 +00:00
$dataarray [ $arrayplacement ][ 'count' ] ++ ; // Used for counting total qsos plotted
2020-02-18 09:49:27 +00:00
if ( $dataarray [ $arrayplacement ][ 'callcount' ] < 5 ) { // Used for tooltip in graph, set limit to 5 calls shown
if ( $dataarray [ $arrayplacement ][ 'callcount' ] > 0 ) {
$dataarray [ $arrayplacement ][ 'calls' ] .= ', ' ;
}
$dataarray [ $arrayplacement ][ 'calls' ] .= $qso [ 'callsign' ];
$dataarray [ $arrayplacement ][ 'callcount' ] ++ ;
}
}
2021-09-12 14:46:16 +00:00
$data [ 'ok' ] = 'OK' ;
$data [ 'qrb' ] = $qrb ;
$data [ 'qsodata' ] = $dataarray ;
$data [ 'unit' ] = $unit ;
return $data ;
2020-02-18 09:49:27 +00:00
}
}
/*
* Checks the validity of the locator
* Input : locator
* Returns : bool
*/
function valid_locator ( $loc ) {
$regex = '^[A-R]{2}[0-9]{2}[A-X]{2}$' ;
if ( preg_match ( " % { $regex } %i " , $loc )) {
return true ;
}
else {
return false ;
}
}
/*
* Converts locator to latitude and longitude
* Input : locator
* Returns : array with longitude and latitude
*/
function loc_to_latlon ( $loc ) {
/* lat */
$l [ 0 ] =
( ord ( substr ( $loc , 1 , 1 )) - 65 ) * 10 - 90 +
( ord ( substr ( $loc , 3 , 1 )) - 48 ) +
( ord ( substr ( $loc , 5 , 1 )) - 65 ) / 24 + 1 / 48 ;
$l [ 0 ] = $this -> deg_to_rad ( $l [ 0 ]);
/* lon */
$l [ 1 ] =
( ord ( substr ( $loc , 0 , 1 )) - 65 ) * 20 - 180 +
( ord ( substr ( $loc , 2 , 1 )) - 48 ) * 2 +
( ord ( substr ( $loc , 4 , 1 )) - 65 ) / 12 + 1 / 24 ;
$l [ 1 ] = $this -> deg_to_rad ( $l [ 1 ]);
return $l ;
}
function deg_to_rad ( $deg ) {
return ( M_PI * $deg / 180 );
}
2020-11-20 10:55:55 +00:00
function bearing_dist ( $loc1 , $loc2 , $measurement_base ) {
2020-02-18 09:49:27 +00:00
$loc1 = strtoupper ( $loc1 );
$loc2 = strtoupper ( $loc2 );
2021-09-12 14:46:16 +00:00
2020-02-18 09:49:27 +00:00
if ( strlen ( $loc1 ) == 4 ) $loc1 .= 'MM' ;
if ( strlen ( $loc2 ) == 4 ) $loc2 .= 'MM' ;
if ( ! $this -> valid_locator ( $loc1 ) || ! $this -> valid_locator ( $loc2 )) {
return 0 ;
}
$l1 = $this -> loc_to_latlon ( $loc1 );
$l2 = $this -> loc_to_latlon ( $loc2 );
$co = cos ( $l1 [ 1 ] - $l2 [ 1 ]) * cos ( $l1 [ 0 ]) * cos ( $l2 [ 0 ]) + sin ( $l1 [ 0 ]) * sin ( $l2 [ 0 ]);
$ca = atan2 ( sqrt ( 1 - $co * $co ), $co );
2020-11-20 10:55:55 +00:00
switch ( $measurement_base ) {
case 'M' :
return round ( 6371 * $ca / 1.609344 );
case 'K' :
return round ( 6371 * $ca );
case 'N' :
return round ( 6371 * $ca / 1.852 );
2020-11-20 11:14:30 +00:00
default :
return round ( 6371 * $ca );
2020-11-20 10:55:55 +00:00
}
2020-02-18 09:49:27 +00:00
}
2021-09-12 14:46:16 +00:00
}