当前提交
						3f3df3ea63
					
				
					共有  18 个文件被更改,包括 1219 次插入 和 12 次删除
				
			
		|  | @ -0,0 +1,71 @@ | ||||||
|  | <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); | ||||||
|  | 
 | ||||||
|  | class Bandmap extends CI_Controller { | ||||||
|  | 
 | ||||||
|  | 	function __construct() { | ||||||
|  | 		parent::__construct(); | ||||||
|  | 
 | ||||||
|  | 		$this->load->model('user_model'); | ||||||
|  | 		if(!$this->user_model->authorize(2)) { $this->session->set_flashdata('notice', 'You\'re not allowed to do that!'); redirect('dashboard'); } | ||||||
|  | 		$this->load->model('bands'); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	function index() { | ||||||
|  | 		$this->load->model('cat'); | ||||||
|  | 		$this->load->model('bands'); | ||||||
|  | 		$data['radios'] = $this->cat->radios(); | ||||||
|  | 		$data['bands'] = $this->bands->get_user_bands_for_qso_entry(); | ||||||
|  | 
 | ||||||
|  |         $footerData = []; | ||||||
|  | 		$footerData['scripts'] = [ | ||||||
|  | 			'assets/js/sections/bandmap.js', | ||||||
|  | 		]; | ||||||
|  | 
 | ||||||
|  | 		$data['page_title'] = "DXCluster"; | ||||||
|  | 		$this->load->view('interface_assets/header', $data); | ||||||
|  | 		$this->load->view('bandmap/index'); | ||||||
|  | 		$this->load->view('interface_assets/footer', $footerData); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	function list() { | ||||||
|  | 		$this->load->model('cat'); | ||||||
|  | 		$this->load->model('bands'); | ||||||
|  | 		$data['radios'] = $this->cat->radios(); | ||||||
|  | 		$data['bands'] = $this->bands->get_user_bands_for_qso_entry(); | ||||||
|  | 
 | ||||||
|  | 		$footerData = []; | ||||||
|  | 		$footerData['scripts'] = [ | ||||||
|  | 			'assets/js/moment.min.js', | ||||||
|  | 			'assets/js/datetime-moment.js', | ||||||
|  | 			'assets/js/sections/bandmap_list.js' | ||||||
|  | 		]; | ||||||
|  | 
 | ||||||
|  | 		$CI =& get_instance(); | ||||||
|  | 		// Get Date format
 | ||||||
|  | 		if($CI->session->userdata('user_date_format')) { | ||||||
|  | 			// If Logged in and session exists
 | ||||||
|  | 			$pageData['custom_date_format'] = $CI->session->userdata('user_date_format'); | ||||||
|  | 		} else { | ||||||
|  | 			// Get Default date format from /config/cloudlog.php
 | ||||||
|  | 			$pageData['custom_date_format'] = $CI->config->item('qso_date_format'); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		switch ($pageData['custom_date_format']) { | ||||||
|  | 		case "d/m/y": $pageData['custom_date_format'] = 'DD/MM/YY'; break; | ||||||
|  | 		case "d/m/Y": $pageData['custom_date_format'] = 'DD/MM/YYYY'; break; | ||||||
|  | 		case "m/d/y": $pageData['custom_date_format'] = 'MM/DD/YY'; break; | ||||||
|  | 		case "m/d/Y": $pageData['custom_date_format'] = 'MM/DD/YYYY'; break; | ||||||
|  | 		case "d.m.Y": $pageData['custom_date_format'] = 'DD.MM.YYYY'; break; | ||||||
|  | 		case "y/m/d": $pageData['custom_date_format'] = 'YY/MM/DD'; break; | ||||||
|  | 		case "Y-m-d": $pageData['custom_date_format'] = 'YYYY-MM-DD'; break; | ||||||
|  | 		case "M d, Y": $pageData['custom_date_format'] = 'MMM DD, YYYY'; break; | ||||||
|  | 		case "M d, y": $pageData['custom_date_format'] = 'MMM DD, YY'; break; | ||||||
|  | 		default: $pageData['custom_date_format'] = 'DD/MM/YYYY'; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		$data['page_title'] = "DXCluster"; | ||||||
|  | 		$this->load->view('interface_assets/header', $data); | ||||||
|  | 		$this->load->view('bandmap/list',$pageData); | ||||||
|  | 		$this->load->view('interface_assets/footer', $footerData); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -0,0 +1,53 @@ | ||||||
|  | <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); | ||||||
|  | 
 | ||||||
|  | class Dxcluster extends CI_Controller { | ||||||
|  | 
 | ||||||
|  | 	function __construct() | ||||||
|  | 	{ | ||||||
|  | 		parent::__construct(); | ||||||
|  | 		$this->load->model('user_model'); | ||||||
|  | 		if(!$this->user_model->authorize(2)) { $this->session->set_flashdata('notice', 'You\'re not allowed to do that!'); redirect('dashboard'); } | ||||||
|  | 		$this->load->model('dxcluster_model'); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	function spots($band,$age = '', $de = '') { | ||||||
|  | 		if ($age == '') { | ||||||
|  | 			$age = $this->optionslib->get_option('dxcluster_maxage'); | ||||||
|  | 		} | ||||||
|  | 		if ($de == '') { | ||||||
|  | 			$de = $this->optionslib->get_option('dxcluster_decont'); | ||||||
|  | 		} | ||||||
|  | 		$calls_found=$this->dxcluster_model->dxc_spotlist($band, $age, $de); | ||||||
|  | 			header('Content-Type: application/json'); | ||||||
|  | 		if ($calls_found) { | ||||||
|  | 			echo json_encode($calls_found, JSON_PRETTY_PRINT); | ||||||
|  | 		} else { | ||||||
|  | 			echo '{ "error": "not found" }'; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	function qrg_lookup($qrg) { | ||||||
|  | 		$call_found=$this->dxcluster_model->dxc_qrg_lookup($this->security->xss_clean($qrg)); | ||||||
|  | 			header('Content-Type: application/json'); | ||||||
|  | 		if ($call_found) { | ||||||
|  | 			echo json_encode($call_found, JSON_PRETTY_PRINT); | ||||||
|  | 		} else { | ||||||
|  | 			echo '{ "error": "not found" }'; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	function call($call) { | ||||||
|  | 		$this->load->model('logbook_model'); | ||||||
|  | 
 | ||||||
|  | 		$date = date('Ymd', time()); | ||||||
|  | 		$dxcc = $this->logbook_model->dxcc_lookup($call, $date); | ||||||
|  | 
 | ||||||
|  | 		if ($dxcc) { | ||||||
|  | 			header('Content-Type: application/json'); | ||||||
|  | 			echo json_encode($dxcc, JSON_PRETTY_PRINT); | ||||||
|  | 		} else { | ||||||
|  | 			echo '{ "error": "not found" }'; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -159,12 +159,24 @@ class Options extends CI_Controller { | ||||||
| 		$this->load->library('form_validation'); | 		$this->load->library('form_validation'); | ||||||
| 
 | 
 | ||||||
| 		$this->form_validation->set_rules('dxcache_url', 'URL of DXCache', 'valid_url'); | 		$this->form_validation->set_rules('dxcache_url', 'URL of DXCache', 'valid_url'); | ||||||
|  | 		$this->form_validation->set_rules('dxcluster_maxage', 'Max Age of Spots', 'required'); | ||||||
|  | 		$this->form_validation->set_rules('dxcluster_decont', 'de continent', 'required'); | ||||||
| 
 | 
 | ||||||
| 		if ($this->form_validation->run() == FALSE) { | 		if ($this->form_validation->run() == FALSE) { | ||||||
| 			$this->load->view('interface_assets/header', $data); | 			$this->load->view('interface_assets/header', $data); | ||||||
| 			$this->load->view('options/dxcluster'); | 			$this->load->view('options/dxcluster'); | ||||||
| 			$this->load->view('interface_assets/footer'); | 			$this->load->view('interface_assets/footer'); | ||||||
| 		} else { | 		} else { | ||||||
|  | 			$dxcluster_decont_update = $this->optionslib->update('dxcluster_decont', $this->input->post('dxcluster_decont'), 'yes'); | ||||||
|  | 			if($dxcluster_decont_update == TRUE) { | ||||||
|  | 				$this->session->set_flashdata('success', $this->lang->line('options_dxcluster_decont_changed_to').$this->input->post('dxcluster_decont')); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			$dxcluster_maxage_update = $this->optionslib->update('dxcluster_maxage', $this->input->post('dxcluster_maxage'), 'yes'); | ||||||
|  | 			if($dxcluster_maxage_update == TRUE) { | ||||||
|  | 				$this->session->set_flashdata('success', $this->lang->line('options_dxcluster_maxage_changed_to').$this->input->post('dxcluster_maxage')); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
| 			$dxcache_url_update = $this->optionslib->update('dxcache_url', $this->input->post('dxcache_url'), 'yes'); | 			$dxcache_url_update = $this->optionslib->update('dxcache_url', $this->input->post('dxcache_url'), 'yes'); | ||||||
| 			if($dxcache_url_update == TRUE) { | 			if($dxcache_url_update == TRUE) { | ||||||
| 				$this->session->set_flashdata('success', $this->lang->line('options_dxcache_url_changed_to').$this->input->post('dxcache_url')); | 				$this->session->set_flashdata('success', $this->lang->line('options_dxcache_url_changed_to').$this->input->post('dxcache_url')); | ||||||
|  |  | ||||||
|  | @ -13,6 +13,7 @@ $lang['menu_live_qso'] = 'Live QSO'; | ||||||
| $lang['menu_post_qso'] = 'Post QSO'; | $lang['menu_post_qso'] = 'Post QSO'; | ||||||
| $lang['menu_live_contest_logging'] = 'Live Contest Logging'; | $lang['menu_live_contest_logging'] = 'Live Contest Logging'; | ||||||
| $lang['menu_post_contest_logging'] = 'Post Contest Logging'; | $lang['menu_post_contest_logging'] = 'Post Contest Logging'; | ||||||
|  | $lang['menu_bandmap'] = 'Bandmap'; | ||||||
| $lang['menu_view_qsl'] = 'View QSL'; | $lang['menu_view_qsl'] = 'View QSL'; | ||||||
| $lang['menu_view_eqsl'] = 'View eQSL'; | $lang['menu_view_eqsl'] = 'View eQSL'; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -64,5 +64,10 @@ $lang['options_dxcluster_longtext'] = 'The Provider of the DXCluster-Cache. You | ||||||
| $lang['options_dxcluster_hint'] = 'URL of the DXCluster-Cache. e.g. https://dxc.jo30.de/dxcache'; | $lang['options_dxcluster_hint'] = 'URL of the DXCluster-Cache. e.g. https://dxc.jo30.de/dxcache'; | ||||||
| $lang['options_dxcluster_settings'] = 'DXCluster'; | $lang['options_dxcluster_settings'] = 'DXCluster'; | ||||||
| $lang['options_dxcache_url_changed_to'] = 'DXCluster Cache URL changed to '; | $lang['options_dxcache_url_changed_to'] = 'DXCluster Cache URL changed to '; | ||||||
|  | $lang['options_dxcluster_maxage'] = 'Maximum Age of spots taken care of'; | ||||||
|  | $lang['options_dxcluster_maxage_hint'] = 'The Age in Minutes of spots, that will be taken care at bandplan/lookup'; | ||||||
|  | $lang['options_dxcluster_decont'] = 'Show spots which are spotted from following continent'; | ||||||
|  | $lang['options_dxcluster_maxage_changed_to']='Maximum age of spots changed to '; | ||||||
|  | $lang['options_dxcluster_decont_changed_to']='de continent changed to '; | ||||||
| 
 | 
 | ||||||
| $lang['options_save'] = 'Save'; | $lang['options_save'] = 'Save'; | ||||||
|  |  | ||||||
|  | @ -13,6 +13,7 @@ $lang['menu_live_qso'] = 'Live QSO'; | ||||||
| $lang['menu_post_qso'] = 'Zeitversetztes QSO'; | $lang['menu_post_qso'] = 'Zeitversetztes QSO'; | ||||||
| $lang['menu_live_contest_logging'] = 'Live Contest Logging'; | $lang['menu_live_contest_logging'] = 'Live Contest Logging'; | ||||||
| $lang['menu_post_contest_logging'] = 'Zeitversetztes Contest Logging'; | $lang['menu_post_contest_logging'] = 'Zeitversetztes Contest Logging'; | ||||||
|  | $lang['menu_bandmap'] = 'Bandmap'; | ||||||
| $lang['menu_view_qsl'] = 'QSL Ansicht'; | $lang['menu_view_qsl'] = 'QSL Ansicht'; | ||||||
| $lang['menu_view_eqsl'] = 'eQSL Ansicht'; | $lang['menu_view_eqsl'] = 'eQSL Ansicht'; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -64,6 +64,9 @@ $lang['options_dxcluster_longtext'] = 'Der Provider des DXCluster-Caches. Du kan | ||||||
| $lang['options_dxcluster_hint'] = 'URL des DXCluster-Caches. z.B. https://dxc.jo30.de/dxcache'; | $lang['options_dxcluster_hint'] = 'URL des DXCluster-Caches. z.B. https://dxc.jo30.de/dxcache'; | ||||||
| $lang['options_dxcluster_settings'] = 'DXCluster'; | $lang['options_dxcluster_settings'] = 'DXCluster'; | ||||||
| $lang['options_dxcache_url_changed_to'] = 'DXCluster Cache URL geänder zu '; | $lang['options_dxcache_url_changed_to'] = 'DXCluster Cache URL geänder zu '; | ||||||
| 
 | $lang['options_dxcluster_maxage'] = 'Maximales Alter bis zu dem Spots berücksichtigt werden'; | ||||||
|  | $lang['options_dxcluster_decont'] = 'Nur Spots berücksichtigen, die in folgendem Kontinent erfasst wurden'; | ||||||
|  | $lang['options_dxcluster_maxage_changed_to']='Maximal Spot-Alter geänder auf '; | ||||||
|  | $lang['options_dxcluster_decont_changed_to']='Spotterkontinent geändert auf '; | ||||||
| 
 | 
 | ||||||
| $lang['options_save'] = 'Speichern'; | $lang['options_save'] = 'Speichern'; | ||||||
|  |  | ||||||
|  | @ -0,0 +1,119 @@ | ||||||
|  | <?php | ||||||
|  | 
 | ||||||
|  | use Cloudlog\Dxcc\Dxcc; | ||||||
|  | 
 | ||||||
|  | class Dxcluster_model extends CI_Model { | ||||||
|  |     public function dxc_spotlist($band = '20m', $maxage = 60, $de = '') { | ||||||
|  | 		$this->load->helper(array('psr4_autoloader')); | ||||||
|  | 	    $CI =& get_instance(); | ||||||
|  | 	    if ( ($this->optionslib->get_option('dxcache_url') != '') ) { | ||||||
|  | 		if($CI->session->userdata('user_date_format')) { | ||||||
|  |                         $custom_date_format = $CI->session->userdata('user_date_format'); | ||||||
|  |                 } else { | ||||||
|  |                         $custom_date_format = $CI->config->item('qso_date_format'); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  | 		    $dxcache_url = $this->optionslib->get_option('dxcache_url').'/spots/'.$band; | ||||||
|  | 		    $CI->load->model('logbooks_model'); | ||||||
|  | 			$CI->load->model('logbook_model'); | ||||||
|  | 		    $logbooks_locations_array = $CI->logbooks_model->list_logbook_relationships($this->session->userdata('active_station_logbook')); | ||||||
|  | 
 | ||||||
|  | 		    // CURL Functions
 | ||||||
|  | 		    $ch = curl_init(); | ||||||
|  | 		    curl_setopt($ch, CURLOPT_URL, $dxcache_url); | ||||||
|  | 		    curl_setopt($ch, CURLOPT_USERAGENT, 'Cloudlog DXLookup'); | ||||||
|  | 		    curl_setopt($ch, CURLOPT_HEADER, false); | ||||||
|  | 		    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | ||||||
|  | 		    $jsonraw = curl_exec($ch); | ||||||
|  | 		    curl_close($ch); | ||||||
|  | 		    $json = json_decode($jsonraw); | ||||||
|  | 			$date = date('Ymd', time()); | ||||||
|  | 
 | ||||||
|  | 			$dxccObj = new DXCC($date); | ||||||
|  | 
 | ||||||
|  | 		    // Create JSON object
 | ||||||
|  | 		    if (strlen($jsonraw)>20) { | ||||||
|  | 			    $spotsout=[]; | ||||||
|  | 			    foreach($json as $singlespot){ | ||||||
|  | 				    $spotband = $CI->frequency->GetBand($singlespot->frequency*1000); | ||||||
|  | 				    $singlespot->band=$spotband; | ||||||
|  | 				    if ($band != $spotband) { continue; } | ||||||
|  | 				    $datetimecurrent = new DateTime("now", new DateTimeZone('UTC')); // Today's Date/Time
 | ||||||
|  | 				    $datetimespot = new DateTime($singlespot->when, new DateTimeZone('UTC')); | ||||||
|  | 				    $spotage = $datetimecurrent->diff($datetimespot); | ||||||
|  | 				    $minutes = $spotage->days * 24 * 60; | ||||||
|  | 				    $minutes += $spotage->h * 60; | ||||||
|  | 				    $minutes += $spotage->i; | ||||||
|  | 				    $singlespot->age=$minutes; | ||||||
|  | 				    $singlespot->when_pretty=date($custom_date_format . " H:i", strtotime($singlespot->when)); | ||||||
|  | 
 | ||||||
|  | 				    if ($minutes<=$maxage) { | ||||||
|  | 					    if (!(property_exists($singlespot,'dxcc_spotted'))) {	// Check if we already have dxcc of spotted
 | ||||||
|  | 					    	$dxcc=$dxccObj->dxcc_lookup($singlespot->spotted,date('Ymd', time())); | ||||||
|  | 					    	$singlespot->dxcc_spotted=$dxcc; | ||||||
|  | 					    } | ||||||
|  | 					    if (!(property_exists($singlespot,'dxcc_spotter'))) {	// Check if we already have dxcc of spotter
 | ||||||
|  | 					    	$dxcc=$dxccObj->dxcc_lookup($singlespot->spotter,date('Ymd', time())); | ||||||
|  | 					    	$singlespot->dxcc_spotter=$dxcc; | ||||||
|  | 					    } | ||||||
|  | 					    if ( ($de != '') && ($de != 'Any') && (property_exists($singlespot->dxcc_spotter,'cont')) ){	// If we have a "de continent" and a filter-wish filter on that
 | ||||||
|  | 						    if (strtolower($de) == strtolower($singlespot->dxcc_spotter->cont)) { | ||||||
|  | 							    $singlespot->worked_call = ($this->logbook_model->check_if_callsign_worked_in_logbook($singlespot->spotted, $logbooks_locations_array, $singlespot->band) == 1); | ||||||
|  | 							    array_push($spotsout,$singlespot); | ||||||
|  | 						    } | ||||||
|  | 					    } else {	// No de continent? No Filter --> Just push
 | ||||||
|  | 						    $singlespot->worked_call = ($this->logbook_model->check_if_callsign_worked_in_logbook($singlespot->spotted, $logbooks_locations_array, $singlespot->band) == 1); | ||||||
|  | 						    array_push($spotsout,$singlespot); | ||||||
|  | 					    } | ||||||
|  | 				    } | ||||||
|  | 			    } | ||||||
|  | 			    return ($spotsout); | ||||||
|  | 		    } else { | ||||||
|  | 			    return ''; | ||||||
|  | 		    } | ||||||
|  | 	    } else { | ||||||
|  | 		    return ''; | ||||||
|  | 	    } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function dxc_qrg_lookup($qrg, $maxage = 120) { | ||||||
|  | 		$this->load->helper(array('psr4_autoloader')); | ||||||
|  | 	    if ( ($this->optionslib->get_option('dxcache_url') != '') && (is_numeric($qrg)) ) { | ||||||
|  | 		    $dxcache_url = $this->optionslib->get_option('dxcache_url').'/spot/'.$qrg; | ||||||
|  | 
 | ||||||
|  | 		    // CURL Functions
 | ||||||
|  | 		    $ch = curl_init(); | ||||||
|  | 		    curl_setopt($ch, CURLOPT_URL, $dxcache_url); | ||||||
|  | 		    curl_setopt($ch, CURLOPT_USERAGENT, 'Cloudlog DXLookup by QRG'); | ||||||
|  | 		    curl_setopt($ch, CURLOPT_HEADER, false); | ||||||
|  | 		    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | ||||||
|  | 		    $jsonraw = curl_exec($ch); | ||||||
|  | 		    curl_close($ch); | ||||||
|  | 		    $json = json_decode($jsonraw); | ||||||
|  | 
 | ||||||
|  | 			$date = date('Ymd', time()); | ||||||
|  | 
 | ||||||
|  | 			$dxccObj = new DXCC($date); | ||||||
|  | 
 | ||||||
|  | 		    // Create JSON object
 | ||||||
|  | 			if (strlen($jsonraw)>20) { | ||||||
|  | 			    $datetimecurrent = new DateTime("now", new DateTimeZone('UTC')); // Today's Date/Time
 | ||||||
|  | 			    $datetimespot = new DateTime($json->when, new DateTimeZone('UTC')); | ||||||
|  | 			    $spotage = $datetimecurrent->diff($datetimespot); | ||||||
|  | 			    $minutes = $spotage->days * 24 * 60; | ||||||
|  | 			    $minutes += $spotage->h * 60; | ||||||
|  | 			    $minutes += $spotage->i; | ||||||
|  | 			    $json->age=$minutes; | ||||||
|  | 			    if ($minutes<=$maxage) { | ||||||
|  | 				    $dxcc=$dxccObj->dxcc_lookup($json->spotter,date('Ymd', time())); | ||||||
|  | 				    $json->dxcc_spotter=$dxcc; | ||||||
|  | 				    return ($json); | ||||||
|  | 			    } else { | ||||||
|  | 				    return ''; | ||||||
|  | 			    } | ||||||
|  | 		    } else { | ||||||
|  | 			    return ''; | ||||||
|  | 		    } | ||||||
|  | 	    } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -3992,7 +3992,6 @@ class Logbook_model extends CI_Model { | ||||||
|         } |         } | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function validateADIFDate($date, $format = 'Ymd') | function validateADIFDate($date, $format = 'Ymd') | ||||||
|  |  | ||||||
|  | @ -0,0 +1,66 @@ | ||||||
|  | <script> | ||||||
|  | 	var dxcluster_provider="<?php echo base_url(); ?>index.php/dxcluster"; | ||||||
|  | 	var dxcluster_maxage=<?php echo $this->optionslib->get_option('dxcluster_maxage'); ?>;
 | ||||||
|  | 	var cat_timeout_interval="<?php echo $this->optionslib->get_option('cat_timeout_interval'); ?>"; | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | <div class="container"> | ||||||
|  | <br> | ||||||
|  | <center><button type="button" class="btn" id="menutoggle"><i class="fa fa-arrow-up" id="menutoggle_i"></i></button></center> | ||||||
|  | <h2 id="dxtitle"><?php echo $page_title; ?></h2>
 | ||||||
|  | <div class="tabs" id="dxtabs"> | ||||||
|  | 		<ul class="nav nav-tabs" id="myTab" role="tablist"> | ||||||
|  | 			<li class="nav-item"> | ||||||
|  | 				<a class="nav-link active" href="index">BandMap</a> | ||||||
|  | 			</li> | ||||||
|  | 			<li class="nav-item"> | ||||||
|  | 				<a class="nav-link" href="list">BandList</a> | ||||||
|  | 			</li> | ||||||
|  | 		</ul> | ||||||
|  | </div> | ||||||
|  | <div class="tab-content" id="myTabContent"> | ||||||
|  | <div class="messages my-1 mr-2"></div> | ||||||
|  | <div class="form-inline"> | ||||||
|  | 		<label class="my-1 mr-2" for="radio"><?php echo lang('gen_hamradio_radio'); ?></label>
 | ||||||
|  | 		<select class="form-control-sm radios my-1 mr-sm-2" id="radio" name="radio"> | ||||||
|  | 			<option value="0" selected="selected"><?php echo lang('general_word_none'); ?></option>
 | ||||||
|  | 			<?php foreach ($radios->result() as $row) { ?>
 | ||||||
|  | 			<option value="<?php echo $row->id; ?>" <?php if($this->session->userdata('radio') == $row->id) { echo "selected=\"selected\""; } ?>><?php echo $row->radio; ?></option>
 | ||||||
|  | 			<?php } ?>
 | ||||||
|  | 		</select> | ||||||
|  | 
 | ||||||
|  | 		<label class="my-1 mr-2" for="decontSelect">Spots de</label> | ||||||
|  | 		<select class="form-control-sm my-1 mr-sm-2" id="decontSelect" name="dxcluster_decont" aria-describedby="dxcluster_decontHelp" required> | ||||||
|  | 				<option value="Any">*</option> | ||||||
|  | 				<option value="AF"<?php if ($this->optionslib->get_option('dxcluster_decont') == 'AF') { echo " selected"; } ?>>Africa</option>
 | ||||||
|  | 				<option value="AN"<?php if ($this->optionslib->get_option('dxcluster_decont') == 'AN') { echo " selected"; } ?>>Antarctica</option>
 | ||||||
|  | 				<option value="AS"<?php if ($this->optionslib->get_option('dxcluster_decont') == 'AS') { echo " selected"; } ?>>Asia</option>
 | ||||||
|  | 				<option value="EU"<?php if ($this->optionslib->get_option('dxcluster_decont') == 'EU') { echo " selected"; } ?>>Europe</option>
 | ||||||
|  | 				<option value="NA"<?php if ($this->optionslib->get_option('dxcluster_decont') == 'NA') { echo " selected"; } ?>>North America</option>
 | ||||||
|  | 				<option value="OC"<?php if ($this->optionslib->get_option('dxcluster_decont') == 'OC') { echo " selected"; } ?>>Oceania</option>
 | ||||||
|  | 				<option value="SA"<?php if ($this->optionslib->get_option('dxcluster_decont') == 'SA') { echo " selected"; } ?>>South America</option>
 | ||||||
|  |                 </select> | ||||||
|  | 
 | ||||||
|  | 		<label class="my-1 mr-2" for="band"><?php echo lang('gen_hamradio_band'); ?></label>
 | ||||||
|  | 		<select id="band" class="form-control-sm my-1 mr-sm-2" name="band"> | ||||||
|  | 			<?php foreach($bands as $key=>$bandgroup) { | ||||||
|  | 					echo '<optgroup label="' . strtoupper($key) . '">'; | ||||||
|  | 					foreach($bandgroup as $band) { | ||||||
|  | 					echo '<option value="' . $band . '"'; | ||||||
|  | 						if ($band == "20m") echo ' selected'; | ||||||
|  | 						echo '>' . $band . '</option>'."\n"; | ||||||
|  | 					} | ||||||
|  | 					echo '</optgroup>'; | ||||||
|  | 				} | ||||||
|  | 			?>
 | ||||||
|  | 		</select> | ||||||
|  | 	</div> | ||||||
|  | 
 | ||||||
|  | <figure class="highcharts-figure"> | ||||||
|  |     <div id="bandmap"></div> | ||||||
|  |     <p class="highcharts-description"> | ||||||
|  |     </p> | ||||||
|  | </figure> | ||||||
|  | </div> | ||||||
|  | </div> | ||||||
|  | @ -0,0 +1,91 @@ | ||||||
|  | <script> | ||||||
|  | 	var dxcluster_provider="<?php echo base_url(); ?>index.php/dxcluster"; | ||||||
|  | 	var cat_timeout_interval="<?php echo $this->optionslib->get_option('cat_timeout_interval'); ?>"; | ||||||
|  | 	var dxcluster_maxage=<?php echo $this->optionslib->get_option('dxcluster_maxage'); ?>;
 | ||||||
|  | 	var custom_date_format = "<?php echo $custom_date_format ?>"; | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <style> | ||||||
|  | .fresh{ | ||||||
|  |     -webkit-transition: all 15s ease; | ||||||
|  |     -moz-transition: all 15s ease; | ||||||
|  |     -o-transition: all 15s ease; | ||||||
|  |     transition: all 15s ease; | ||||||
|  | } | ||||||
|  | </style> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | <div class="container"> | ||||||
|  | <br> | ||||||
|  | <center><button type="button" class="btn" id="menutoggle"><i class="fa fa-arrow-up" id="menutoggle_i"></i></button></center> | ||||||
|  | 
 | ||||||
|  | <h2 id="dxtitle"><?php echo $page_title; ?></h2>
 | ||||||
|  | 
 | ||||||
|  | <div id="dxtabs" class="tabs"> | ||||||
|  | 		<ul class="nav nav-tabs" id="myTab" role="tablist"> | ||||||
|  | 			<li class="nav-item"> | ||||||
|  | 				<a class="nav-link" href="index">BandMap</a> | ||||||
|  | 			</li> | ||||||
|  | 			<li class="nav-item"> | ||||||
|  | 				<a class="nav-link active" href="list">BandList</a> | ||||||
|  | 			</li> | ||||||
|  | 		</ul> | ||||||
|  | </div> | ||||||
|  | 
 | ||||||
|  | <div class="tab-content" id="myTabContent"> | ||||||
|  | <div class="messages my-1 mr-2"></div> | ||||||
|  | <div class="form-inline"> | ||||||
|  | 		<label class="my-1 mr-2" for="radio"><?php echo lang('gen_hamradio_radio'); ?></label>
 | ||||||
|  | 		<select class="form-control-sm radios my-1 mr-sm-2" id="radio" name="radio"> | ||||||
|  | 			<option value="0" selected="selected"><?php echo lang('general_word_none'); ?></option>
 | ||||||
|  | 			<?php foreach ($radios->result() as $row) { ?>
 | ||||||
|  | 			<option value="<?php echo $row->id; ?>" <?php if($this->session->userdata('radio') == $row->id) { echo "selected=\"selected\""; } ?>><?php echo $row->radio; ?></option>
 | ||||||
|  | 			<?php } ?>
 | ||||||
|  | 		</select> | ||||||
|  | 		<label class="my-1 mr-2" for="decontSelect">Spots de</label> | ||||||
|  | 		<select class="form-control-sm my-1 mr-sm-2" id="decontSelect" name="dxcluster_decont" aria-describedby="dxcluster_decontHelp" required> | ||||||
|  | 				<option value="Any">*</option> | ||||||
|  | 				<option value="AF"<?php if ($this->optionslib->get_option('dxcluster_decont') == 'AF') { echo " selected"; } ?>>Africa</option>
 | ||||||
|  | 				<option value="AN"<?php if ($this->optionslib->get_option('dxcluster_decont') == 'AN') { echo " selected"; } ?>>Antarctica</option>
 | ||||||
|  | 				<option value="AS"<?php if ($this->optionslib->get_option('dxcluster_decont') == 'AS') { echo " selected"; } ?>>Asia</option>
 | ||||||
|  | 				<option value="EU"<?php if ($this->optionslib->get_option('dxcluster_decont') == 'EU') { echo " selected"; } ?>>Europe</option>
 | ||||||
|  | 				<option value="NA"<?php if ($this->optionslib->get_option('dxcluster_decont') == 'NA') { echo " selected"; } ?>>North America</option>
 | ||||||
|  | 				<option value="OC"<?php if ($this->optionslib->get_option('dxcluster_decont') == 'OC') { echo " selected"; } ?>>Oceania</option>
 | ||||||
|  | 				<option value="SA"<?php if ($this->optionslib->get_option('dxcluster_decont') == 'SA') { echo " selected"; } ?>>South America</option>
 | ||||||
|  |                 </select> | ||||||
|  | 
 | ||||||
|  | 		<label class="my-1 mr-2" for="band"><?php echo lang('gen_hamradio_band'); ?></label>
 | ||||||
|  | 		<select id="band" class="form-control-sm my-1 mr-sm-2" name="band"> | ||||||
|  | 			<?php foreach($bands as $key=>$bandgroup) { | ||||||
|  | 					echo '<optgroup label="' . strtoupper($key) . '">'; | ||||||
|  | 					foreach($bandgroup as $band) { | ||||||
|  | 					echo '<option value="' . $band . '"'; | ||||||
|  | 						if ($band == "20m") echo ' selected'; | ||||||
|  | 						echo '>' . $band . '</option>'."\n"; | ||||||
|  | 					} | ||||||
|  | 					echo '</optgroup>'; | ||||||
|  | 				} | ||||||
|  | 			?>
 | ||||||
|  | 		</select> | ||||||
|  | 	</div> | ||||||
|  | 
 | ||||||
|  |                 <p> | ||||||
|  | 
 | ||||||
|  |                 <table style="width:100%" class="table-sm table spottable table-bordered table-hover table-striped table-condensed"> | ||||||
|  |                     <thead> | ||||||
|  |                         <tr class="log_title titles"> | ||||||
|  |                             <th><?php echo lang('general_word_date'); ?>/<?php echo lang('general_word_time'); ?></th>
 | ||||||
|  | 			    <th><?php echo lang('gen_hamradio_frequency'); ?></th>
 | ||||||
|  |                             <th><?php echo lang('gen_hamradio_call'); ?></th>
 | ||||||
|  | 			    <th>DXCC</th> | ||||||
|  |                             <th><?php echo lang('gen_hamradio_call'); ?> Spotter</th>
 | ||||||
|  |                         </tr> | ||||||
|  |                     </thead> | ||||||
|  | 
 | ||||||
|  |                     <tbody class="spots_table_contents"> | ||||||
|  |                     </tbody> | ||||||
|  |                 </table> | ||||||
|  |             </div> | ||||||
|  | 
 | ||||||
|  | </div> | ||||||
|  | </div> | ||||||
|  | @ -937,10 +937,10 @@ $(document).on('keypress',function(e) { | ||||||
| 
 | 
 | ||||||
| 	if ($this->optionslib->get_option('dxcache_url') != ''){ ?>
 | 	if ($this->optionslib->get_option('dxcache_url') != ''){ ?>
 | ||||||
| 	<script type="text/javascript"> | 	<script type="text/javascript"> | ||||||
| 		var dxcluster_provider =' <?php echo $this->optionslib->get_option('dxcache_url'); ?>'; | 		var dxcluster_provider = '<?php echo base_url(); ?>index.php/dxcluster'; | ||||||
| 		$(document).ready(function() { | 		$(document).ready(function() { | ||||||
| 			$("#check_cluster").on("click", function() { | 			$("#check_cluster").on("click", function() { | ||||||
| 				$.ajax({ url: dxcluster_provider+"/spot/"+$("#frequency").val()/1000, cache: false, dataType: "json" }).done( | 				$.ajax({ url: dxcluster_provider+"/qrg_lookup/"+$("#frequency").val()/1000, cache: false, dataType: "json" }).done( | ||||||
| 					function(dxspot) { | 					function(dxspot) { | ||||||
| 						$("#callsign").val(dxspot.spotted); | 						$("#callsign").val(dxspot.spotted); | ||||||
| 						$("#callsign").trigger("blur"); | 						$("#callsign").trigger("blur"); | ||||||
|  | @ -2911,6 +2911,15 @@ function viewEqsl(picture, callsign) { | ||||||
| 	</script> | 	</script> | ||||||
| <?php } ?>
 | <?php } ?>
 | ||||||
| 
 | 
 | ||||||
|  | <?php if ($this->uri->segment(1) == "bandmap") { ?>
 | ||||||
|  | 
 | ||||||
|  | 	<script src="https://code.highcharts.com/highcharts.js"></script> | ||||||
|  | 	<script src="https://code.highcharts.com/modules/timeline.js"></script> | ||||||
|  | 	<script src="https://code.highcharts.com/modules/exporting.js"></script> | ||||||
|  | 	<script src="https://code.highcharts.com/modules/accessibility.js"></script> | ||||||
|  | 
 | ||||||
|  | <?php } ?>
 | ||||||
|  | 
 | ||||||
| <?php if ($this->uri->segment(1) == "awards") { | <?php if ($this->uri->segment(1) == "awards") { | ||||||
| 	// Get Date format
 | 	// Get Date format
 | ||||||
| 	if($this->session->userdata('user_date_format')) { | 	if($this->session->userdata('user_date_format')) { | ||||||
|  |  | ||||||
|  | @ -80,6 +80,10 @@ | ||||||
| 							<a class="dropdown-item" href="<?php echo site_url('contesting?manual=0');?>" title="Live contest QSOs"><i class="fas fa-list"></i> <?php echo lang('menu_live_contest_logging'); ?></a>
 | 							<a class="dropdown-item" href="<?php echo site_url('contesting?manual=0');?>" title="Live contest QSOs"><i class="fas fa-list"></i> <?php echo lang('menu_live_contest_logging'); ?></a>
 | ||||||
| 							<div class="dropdown-divider"></div> | 							<div class="dropdown-divider"></div> | ||||||
| 							<a class="dropdown-item" href="<?php echo site_url('contesting?manual=1');?>" title="Post contest QSOs"><i class="fas fa-list"></i> <?php echo lang('menu_post_contest_logging'); ?></a>
 | 							<a class="dropdown-item" href="<?php echo site_url('contesting?manual=1');?>" title="Post contest QSOs"><i class="fas fa-list"></i> <?php echo lang('menu_post_contest_logging'); ?></a>
 | ||||||
|  | <?php if ($this->optionslib->get_option('dxcache_url') != '') { ?>
 | ||||||
|  | 							<div class="dropdown-divider"></div> | ||||||
|  | 							<a class="dropdown-item" href="<?php echo site_url('bandmap/index');?>" title="Bandmap"><i class="fa fa-id-card"></i> <?php echo lang('menu_bandmap'); ?></a>
 | ||||||
|  | <?php } ?>
 | ||||||
| 							<div class="dropdown-divider"></div> | 							<div class="dropdown-divider"></div> | ||||||
| 							<a class="dropdown-item" href="<?php echo site_url('qsl');?>" title="QSL"><i class="fa fa-id-card"></i> <?php echo lang('menu_view_qsl'); ?></a>
 | 							<a class="dropdown-item" href="<?php echo site_url('qsl');?>" title="QSL"><i class="fa fa-id-card"></i> <?php echo lang('menu_view_qsl'); ?></a>
 | ||||||
| 							<div class="dropdown-divider"></div> | 							<div class="dropdown-divider"></div> | ||||||
|  |  | ||||||
|  | @ -40,6 +40,28 @@ | ||||||
|                             <input type="text" name="dxcache_url" class="form-control" id="dxcache_url" aria-describedby="dxcache_urlHelp" value="<?php echo $this->optionslib->get_option('dxcache_url'); ?>"> |                             <input type="text" name="dxcache_url" class="form-control" id="dxcache_url" aria-describedby="dxcache_urlHelp" value="<?php echo $this->optionslib->get_option('dxcache_url'); ?>"> | ||||||
|                             <small id="dxcache_urlHelp" class="form-text text-muted"><?php echo lang('options_dxcluster_hint'); ?></small>
 |                             <small id="dxcache_urlHelp" class="form-text text-muted"><?php echo lang('options_dxcluster_hint'); ?></small>
 | ||||||
|                         </div> |                         </div> | ||||||
|  |                         <div class="form-group"> | ||||||
|  |                             <label for="maxAgeSelect"><?php echo lang('options_dxcluster_maxage'); ?></label>
 | ||||||
|  |                             <select class="custom-select" id="maxAgeSelect" name="dxcluster_maxage" aria-describedby="dxcluster_maxageHelp" required> | ||||||
|  | 				<option value="120"<?php if ($this->optionslib->get_option('dxcluster_maxage') == '120') { echo " selected"; } ?>>2 Hours</option>
 | ||||||
|  | 				<option value="60"<?php if ($this->optionslib->get_option('dxcluster_maxage') == '60') { echo " selected"; } ?>>60 Minutes</option>
 | ||||||
|  | 				<option value="30"<?php if ($this->optionslib->get_option('dxcluster_maxage') == '30') { echo " selected"; } ?>>30 Minutes</option>
 | ||||||
|  |                                 </select> | ||||||
|  |                             <small id="dxcluster_maxageHelp" class="form-text text-muted"><?php echo lang('options_dxcluster_maxage_hint'); ?></small>
 | ||||||
|  |                         </div> | ||||||
|  | 			<div class="form-group"> | ||||||
|  |                             <label for="decontSelect"><?php echo lang('options_dxcluster_decont'); ?></label>
 | ||||||
|  |                             <select class="custom-select" id="decontSelect" name="dxcluster_decont" aria-describedby="dxcluster_decontHelp" required> | ||||||
|  | 				<option value="AF"<?php if ($this->optionslib->get_option('dxcluster_decont') == 'AF') { echo " selected"; } ?>>Africa</option>
 | ||||||
|  | 				<option value="AN"<?php if ($this->optionslib->get_option('dxcluster_decont') == 'AN') { echo " selected"; } ?>>Antarctica</option>
 | ||||||
|  | 				<option value="AS"<?php if ($this->optionslib->get_option('dxcluster_decont') == 'AS') { echo " selected"; } ?>>Asia</option>
 | ||||||
|  | 				<option value="EU"<?php if ($this->optionslib->get_option('dxcluster_decont') == 'EU') { echo " selected"; } ?>>Europe</option>
 | ||||||
|  | 				<option value="NA"<?php if ($this->optionslib->get_option('dxcluster_decont') == 'NA') { echo " selected"; } ?>>North America</option>
 | ||||||
|  | 				<option value="OC"<?php if ($this->optionslib->get_option('dxcluster_decont') == 'OC') { echo " selected"; } ?>>Oceania</option>
 | ||||||
|  | 				<option value="SA"<?php if ($this->optionslib->get_option('dxcluster_decont') == 'SA') { echo " selected"; } ?>>South America</option>
 | ||||||
|  |                                 </select> | ||||||
|  |                             <small id="dxcluster_decontHelp" class="form-text text-muted"><?php echo lang('options_dxcluster_decont_hint'); ?></small>
 | ||||||
|  |                         </div> | ||||||
|   |   | ||||||
|                         <!-- Save the Form --> |                         <!-- Save the Form --> | ||||||
|                         <input class="btn btn-primary" type="submit" value="<?php echo lang('options_save'); ?>" /> |                         <input class="btn btn-primary" type="submit" value="<?php echo lang('options_save'); ?>" /> | ||||||
|  |  | ||||||
|  | @ -458,3 +458,53 @@ div#station_logbooks_linked_table_paginate { | ||||||
| .lotw_info_red { | .lotw_info_red { | ||||||
|    background-image: linear-gradient(to bottom, #3fb618, red); |    background-image: linear-gradient(to bottom, #3fb618, red); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | .highcharts-strong { | ||||||
|  |     font-weight: bold; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .highcharts-figure, | ||||||
|  | .highcharts-data-table table { | ||||||
|  |     min-width: 320px; | ||||||
|  |     max-width: 100%; | ||||||
|  |     margin: 1em auto; | ||||||
|  | 	max-height: calc(100vh - 200px) !important; | ||||||
|  | 	overflow-y: auto;	 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .highcharts-data-table table { | ||||||
|  |     font-family: Verdana, sans-serif; | ||||||
|  |     border-collapse: collapse; | ||||||
|  |     border: 1px solid #ebebeb; | ||||||
|  |     margin: 10px auto; | ||||||
|  |     text-align: center; | ||||||
|  |     width: 100%; | ||||||
|  |     max-width: 500px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .highcharts-data-table caption { | ||||||
|  |     padding: 1em 0; | ||||||
|  |     font-size: 1.2em; | ||||||
|  |     color: #555; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .highcharts-data-table th { | ||||||
|  |     font-weight: 600; | ||||||
|  |     padding: 0.5em; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .highcharts-data-table td, | ||||||
|  | .highcharts-data-table th, | ||||||
|  | .highcharts-data-table caption { | ||||||
|  |     padding: 0.5em; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .highcharts-data-table thead tr, | ||||||
|  | .highcharts-data-table tr:nth-child(even) { | ||||||
|  |     background: #f8f8f8; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .highcharts-data-table tr:hover { | ||||||
|  |     background: #f1f7ff; | ||||||
|  | } | ||||||
							
								
								
									
										254
									
								
								assets/js/sections/bandmap.js
									
									
									
									
									
										普通文件
									
								
							
							
						
						
									
										254
									
								
								assets/js/sections/bandmap.js
									
									
									
									
									
										普通文件
									
								
							|  | @ -0,0 +1,254 @@ | ||||||
|  | $(function() { | ||||||
|  | 	(function(H) { | ||||||
|  | 		H.seriesTypes.timeline.prototype.distributeDL = function() { | ||||||
|  | 			var series = this, | ||||||
|  | 				dataLabelsOptions = series.options.dataLabels, | ||||||
|  | 				options, | ||||||
|  | 				pointDLOptions, | ||||||
|  | 				newOptions = {}, | ||||||
|  | 				visibilityIndex = 1, | ||||||
|  | 				j = 2, | ||||||
|  | 				distance; | ||||||
|  | 
 | ||||||
|  | 			series.points.forEach(function(point, i) { | ||||||
|  | 				distance = dataLabelsOptions.distance; | ||||||
|  | 
 | ||||||
|  | 				if (point.visible && !point.isNull) { | ||||||
|  | 					options = point.options; | ||||||
|  | 					pointDLOptions = point.options.dataLabels; | ||||||
|  | 
 | ||||||
|  | 					if (!series.hasRendered) { | ||||||
|  | 						point.userDLOptions = H.merge({}, pointDLOptions); | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					/* | ||||||
|  | 					if (i === j || i === j + 1) { | ||||||
|  | 						distance = distance * 2.5 | ||||||
|  | 
 | ||||||
|  | 						if (i === j + 1) { | ||||||
|  | 							j += 4 | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 					*/ | ||||||
|  | 					if (i % 6 == 0) { distance = distance * 1; } | ||||||
|  | 					if (i % 6 == 1) { distance = distance * -1; } | ||||||
|  | 					if (i % 6 == 2) { distance = distance * 2; } | ||||||
|  | 					if (i % 6 == 3) { distance = distance * -2; } | ||||||
|  | 					if (i % 6 == 4) { distance = distance * 3; } | ||||||
|  | 					if (i % 6 == 5) { distance = distance * -3; } | ||||||
|  | 
 | ||||||
|  | 					newOptions[series.chart.inverted ? 'x' : 'y'] = distance; | ||||||
|  | 					// newOptions[series.chart.inverted ? 'x' : 'y'] = dataLabelsOptions.alternate && (visibilityIndex % 3 != 0) ?  -distance : distance;
 | ||||||
|  | 
 | ||||||
|  | 					options.dataLabels = H.merge(newOptions, point.userDLOptions); | ||||||
|  | 					visibilityIndex++; | ||||||
|  | 				} | ||||||
|  | 			}); | ||||||
|  | 		} | ||||||
|  | 	}(Highcharts)); | ||||||
|  | 
 | ||||||
|  | 	var bandMapChart; | ||||||
|  | 	var color = ifDarkModeThemeReturn('white', 'grey'); | ||||||
|  | 
 | ||||||
|  | 	function render_chart (band,spot_data) { | ||||||
|  | 		let chartObject=Highcharts.chart('bandmap', { | ||||||
|  | 			chart: { | ||||||
|  | 				type: 'timeline', | ||||||
|  | 				zoomType: 'x', | ||||||
|  | 				inverted: true, | ||||||
|  | 				backgroundColor: getBodyBackground(), | ||||||
|  | 				height: '800px' | ||||||
|  | 			}, | ||||||
|  | 			accessibility: { | ||||||
|  | 				screenReaderSection: { | ||||||
|  | 					beforeChartFormat: '<h5>{chartTitle}</h5>' + | ||||||
|  | 						'<div>{typeDescription}</div>' + | ||||||
|  | 						'<div>{chartSubtitle}</div>' + | ||||||
|  | 						'<div>{chartLongdesc}</div>' + | ||||||
|  | 						'<div>{viewTableButton}</div>' | ||||||
|  | 				}, | ||||||
|  | 				point: { | ||||||
|  | 					valueDescriptionFormat: '{index}. {point.label}. {point.description}.' | ||||||
|  | 				} | ||||||
|  | 			}, | ||||||
|  | 			xAxis: { | ||||||
|  | 				lineColor: color, | ||||||
|  | 				visible: true, | ||||||
|  | 				type: 'linear', | ||||||
|  | 				labels: { | ||||||
|  | 					style: { | ||||||
|  | 						color: color, | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			}, | ||||||
|  | 			yAxis: { | ||||||
|  | 				visible: false, | ||||||
|  | 			}, | ||||||
|  | 			title: { | ||||||
|  | 				text: band, | ||||||
|  | 				style: { | ||||||
|  | 					color: color | ||||||
|  | 				} | ||||||
|  | 			}, | ||||||
|  | 			series: [ { data: spot_data } ] | ||||||
|  | 		}); | ||||||
|  | 		return chartObject; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 				function SortByQrg(a, b){ | ||||||
|  | 					var a = a.frequency; | ||||||
|  | 					var b = b.frequency; | ||||||
|  | 					return ((a< b) ? -1 : ((a> b) ? 1 : 0)); | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				function reduce_spots(spotobject) { | ||||||
|  | 					let unique=[]; | ||||||
|  | 					spotobject.forEach((single) => { | ||||||
|  | 						if (!spotobject.find((item) => ((item.spotted == single.spotted) && (item.frequency == single.frequency) && (Date.parse(item.when)>Date.parse(single.when))))) { | ||||||
|  | 							unique.push(single); | ||||||
|  | 						} | ||||||
|  | 					}); | ||||||
|  | 					return unique; | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				function convert2high(spotobject) { | ||||||
|  | 					let ret={}; | ||||||
|  | 					ret.name=spotobject.spotted; | ||||||
|  | 					ret.x=spotobject.frequency; | ||||||
|  | 					ret.description=spotobject.frequency + " / "+Math.round( (Date.now() - Date.parse(spotobject.when)) / 1000 / 60)+"min. ago"; | ||||||
|  | 					ret.dataLabels={}; | ||||||
|  | 					ret.dataLabels.alternate=true; | ||||||
|  | 					ret.dataLabels.distance=200; | ||||||
|  | 					return ret; | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				function update_chart(band,maxAgeMinutes) { | ||||||
|  | 					if ((band != '') && (band !== undefined)) { | ||||||
|  | 					let dxurl = dxcluster_provider + "/spots/" + band + "/" +maxAgeMinutes; | ||||||
|  | 					$.ajax({ | ||||||
|  | 						url: dxurl, | ||||||
|  | 						cache: false, | ||||||
|  | 						dataType: "json" | ||||||
|  | 					}).done(function(dxspots) { | ||||||
|  | 						spots4chart=[]; | ||||||
|  | 						if (dxspots.length>0) { | ||||||
|  | 							dxspots.sort(SortByQrg); | ||||||
|  | 							dxspots=reduce_spots(dxspots); | ||||||
|  | 							dxspots.forEach((single) => { | ||||||
|  | 								spots4chart.push(convert2high(single)); | ||||||
|  | 							}); | ||||||
|  | 						} | ||||||
|  | 						bandMapChart.title.text=band; | ||||||
|  | 						bandMapChart.series[0].setData(spots4chart); | ||||||
|  | 						bandMapChart.redraw(); | ||||||
|  | 					}); | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 				function set_chart(band, de, maxAgeMinutes) { | ||||||
|  | 					if ((band != '') && (band !== undefined)) { | ||||||
|  | 					let dxurl = dxcluster_provider + "/spots/" + band + "/" +maxAgeMinutes + "/" + de; | ||||||
|  | 					$.ajax({ | ||||||
|  | 						url: dxurl, | ||||||
|  | 						cache: false, | ||||||
|  | 						dataType: "json" | ||||||
|  | 					}).done(function(dxspots) { | ||||||
|  | 						spots4chart=[]; | ||||||
|  | 						if (dxspots.length>0) { | ||||||
|  | 							dxspots.sort(SortByQrg); | ||||||
|  | 							dxspots=reduce_spots(dxspots); | ||||||
|  | 							dxspots.forEach((single) => { | ||||||
|  | 								spots4chart.push(convert2high(single)); | ||||||
|  | 							}); | ||||||
|  | 						} | ||||||
|  | 						bandMapChart=render_chart(band,spots4chart); | ||||||
|  | 					}); | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 	$("#menutoggle").on("click", function() { | ||||||
|  | 		if ($('.navbar').is(":hidden")) { | ||||||
|  | 			$('.navbar').show(); | ||||||
|  | 			$('#dxtabs').show(); | ||||||
|  | 			$('#dxtitle').show(); | ||||||
|  | 			$('#menutoggle_i').removeClass('fa-arrow-down'); | ||||||
|  | 			$('#menutoggle_i').addClass('fa-arrow-up'); | ||||||
|  | 		} else { | ||||||
|  | 			$('.navbar').hide(); | ||||||
|  | 			$('#dxtabs').hide(); | ||||||
|  | 			$('#dxtitle').hide(); | ||||||
|  | 			$('#menutoggle_i').removeClass('fa-arrow-up'); | ||||||
|  | 			$('#menutoggle_i').addClass('fa-arrow-down'); | ||||||
|  | 		} | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	set_chart($('#band option:selected').val(), $('#decontSelect option:selected').val(), dxcluster_maxage); | ||||||
|  | 	setInterval(function () { update_chart($('#band option:selected').val(),dxcluster_maxage); },60000); | ||||||
|  | 	$("#band").on("change",function() { | ||||||
|  | 		set_chart($('#band option:selected').val(), $('#decontSelect option:selected').val(), dxcluster_maxage); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	$("#decontSelect").on("change",function() { | ||||||
|  | 		set_chart($('#band option:selected').val(), $('#decontSelect option:selected').val(), dxcluster_maxage); | ||||||
|  | 	}); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | var updateFromCAT = function() { | ||||||
|  | 	if($('select.radios option:selected').val() != '0') { | ||||||
|  | 		radioID = $('select.radios option:selected').val(); | ||||||
|  | 		$.getJSON( base_url + "radio/json/" + radioID, function( data ) { | ||||||
|  | 
 | ||||||
|  | 			if (data.error) { | ||||||
|  | 				if (data.error == 'not_logged_in') { | ||||||
|  | 					$(".radio_cat_state" ).remove(); | ||||||
|  | 					if($('.radio_login_error').length == 0) { | ||||||
|  | 						$('.messages').prepend('<div class="alert alert-danger radio_login_error" role="alert"><i class="fas fa-broadcast-tower"></i> You\'re not logged it. Please <a href="'+base_url+'">login</a></div>'); | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 				// Put future Errorhandling here
 | ||||||
|  | 			} else { | ||||||
|  | 				if($('.radio_login_error').length != 0) { | ||||||
|  | 					$(".radio_login_error" ).remove(); | ||||||
|  | 				} | ||||||
|  | 				var band = frequencyToBand(data.frequency); | ||||||
|  | 
 | ||||||
|  | 				if (band !== $("#band").val()) { | ||||||
|  | 					$("#band").val(band); | ||||||
|  | 					$("#band").trigger("change"); | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				var minutes = Math.floor(cat_timeout_interval / 60); | ||||||
|  | 
 | ||||||
|  | 				if(data.updated_minutes_ago > minutes) { | ||||||
|  | 					$(".radio_cat_state" ).remove(); | ||||||
|  | 					if($('.radio_timeout_error').length == 0) { | ||||||
|  | 						$('.messages').prepend('<div class="alert alert-danger radio_timeout_error" role="alert"><i class="fas fa-broadcast-tower"></i> Radio connection timed-out: ' + $('select.radios option:selected').text() + ' data is ' + data.updated_minutes_ago + ' minutes old.</div>'); | ||||||
|  | 					} else { | ||||||
|  | 						$('.radio_timeout_error').html('Radio connection timed-out: ' + $('select.radios option:selected').text() + ' data is ' + data.updated_minutes_ago + ' minutes old.'); | ||||||
|  | 					} | ||||||
|  | 				} else { | ||||||
|  | 					$(".radio_timeout_error" ).remove(); | ||||||
|  | 					text = '<i class="fas fa-broadcast-tower"></i><span style="margin-left:10px;"></span><b>TX:</b> '+(Math.round(parseInt(data.frequency)/100)/10000).toFixed(4)+' MHz'; | ||||||
|  | 					if(data.mode != null) { | ||||||
|  | 						text = text+'<span style="margin-left:10px"></span>'+data.mode; | ||||||
|  | 					} | ||||||
|  | 					if(data.power != null && data.power != 0) { | ||||||
|  | 						text = text+'<span style="margin-left:10px"></span>'+data.power+' W'; | ||||||
|  | 					} | ||||||
|  | 					if (! $('#radio_cat_state').length) { | ||||||
|  | 						$('.messages').prepend('<div aria-hidden="true"><div id="radio_cat_state" class="alert alert-success radio_cat_state" role="alert">'+text+'</div></div>'); | ||||||
|  | 					} else { | ||||||
|  | 						$('#radio_cat_state').html(text); | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		}); | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | // Update frequency every three second
 | ||||||
|  | setInterval(updateFromCAT, 3000); | ||||||
|  | 
 | ||||||
|  | // If a radios selected from drop down select radio update.
 | ||||||
|  | $('.radios').change(updateFromCAT); | ||||||
							
								
								
									
										177
									
								
								assets/js/sections/bandmap_list.js
									
									
									
									
									
										普通文件
									
								
							
							
						
						
									
										177
									
								
								assets/js/sections/bandmap_list.js
									
									
									
									
									
										普通文件
									
								
							|  | @ -0,0 +1,177 @@ | ||||||
|  | $(function() { | ||||||
|  | 
 | ||||||
|  | 	function SortByQrg(a, b){ | ||||||
|  | 		var a = a.frequency; | ||||||
|  | 		var b = b.frequency; | ||||||
|  | 		return ((a< b) ? -1 : ((a> b) ? 1 : 0)); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	function fill_list(band,de,maxAgeMinutes) { | ||||||
|  | 		var table = $('.spottable').DataTable(); | ||||||
|  | 		if ((band != '') && (band !== undefined)) { | ||||||
|  | 			let dxurl = dxcluster_provider + "/spots/" + band + "/" +maxAgeMinutes + "/" + de; | ||||||
|  | 			$.ajax({ | ||||||
|  | 				url: dxurl, | ||||||
|  | 				cache: false, | ||||||
|  | 				dataType: "json" | ||||||
|  | 			}).done(function(dxspots) { | ||||||
|  | 				table.page.len(50); | ||||||
|  | 				let oldtable=table.data(); | ||||||
|  | 				table.clear(); | ||||||
|  | 				if (dxspots.length>0) { | ||||||
|  | 					dxspots.sort(SortByQrg); | ||||||
|  | 					dxspots.forEach((single) => { | ||||||
|  | 						var data=[]; | ||||||
|  | 						data[0]=[]; | ||||||
|  | 						data[0].push(single.when_pretty); | ||||||
|  | 						data[0].push(single.frequency + " kHz"); | ||||||
|  | 						data[0].push((single.worked_call ?'<span class="text-success">' : '')+single.spotted+(single.worked_call ? '</span>' : '')); | ||||||
|  | 						data[0].push(single.dxcc_spotted.entity); | ||||||
|  | 						data[0].push(single.spotter); | ||||||
|  | 						if (oldtable.length > 0) { | ||||||
|  | 							let update=false; | ||||||
|  | 							oldtable.each( function (srow) { | ||||||
|  | 								if (JSON.stringify(srow) === JSON.stringify(data[0])) { | ||||||
|  | 									update=true; | ||||||
|  | 								}  | ||||||
|  | 							}); | ||||||
|  | 							if (!update) { 	// Sth. Fresh? So highlight
 | ||||||
|  | 								table.rows.add(data).draw().nodes().to$().addClass("fresh bg-info");  | ||||||
|  | 							} else {  | ||||||
|  | 								table.rows.add(data).draw();  | ||||||
|  | 							} | ||||||
|  | 						} else { | ||||||
|  | 							table.rows.add(data).draw(); | ||||||
|  | 						} | ||||||
|  | 					}); | ||||||
|  | 					setTimeout(function(){	// Remove Highlights within 15sec
 | ||||||
|  | 						$(".fresh").removeClass("bg-info"); | ||||||
|  | 					},1000); | ||||||
|  | 				} | ||||||
|  | 			}); | ||||||
|  | 		} else { | ||||||
|  | 			table.clear(); | ||||||
|  | 			table.draw(); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	function highlight_current_qrg(qrg) { | ||||||
|  | 		var table=$('.spottable').DataTable(); | ||||||
|  | 		table.rows().every(function() { | ||||||
|  | 			var d=this.data(); | ||||||
|  | 			var distance=Math.abs(parseInt(d[1].substring(0,d[1].length-4))-qrg); | ||||||
|  | 			if (distance<=20) { | ||||||
|  | 				distance++; | ||||||
|  | 				alpha=(.5/distance); | ||||||
|  | 				this.nodes().to$().css('background-color', 'rgba(0,0,255,' + alpha + ')'); | ||||||
|  | 			} else { | ||||||
|  | 				this.nodes().to$().css('background-color', ''); | ||||||
|  | 			} | ||||||
|  | 		}); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	$('.spottable').DataTable().order([1, 'asc']); | ||||||
|  | 	$('.spottable').DataTable().clear(); | ||||||
|  | 	fill_list($('#band option:selected').val(), $('#decontSelect option:selected').val(),dxcluster_maxage); | ||||||
|  | 	setInterval(function () { fill_list($('#band option:selected').val(), $('#decontSelect option:selected').val(),dxcluster_maxage); },60000); | ||||||
|  | 
 | ||||||
|  | 	$("#decontSelect").on("change",function() { | ||||||
|  | 		$('.spottable').DataTable().clear(); | ||||||
|  | 		fill_list($('#band option:selected').val(), $('#decontSelect option:selected').val(),dxcluster_maxage); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	$("#band").on("change",function() { | ||||||
|  | 		$('.spottable').DataTable().order([1, 'asc']); | ||||||
|  | 		$('.spottable').DataTable().clear(); | ||||||
|  | 		fill_list($('#band option:selected').val(), $('#decontSelect option:selected').val(),dxcluster_maxage); | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	$("#spottertoggle").on("click", function() { | ||||||
|  | 		if ($('.spottable').DataTable().column(4).visible()) { | ||||||
|  | 			$('.spottable').DataTable().column(4).visible(false); | ||||||
|  | 		} else { | ||||||
|  | 			$('.spottable').DataTable().column(4).visible(true); | ||||||
|  | 		} | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	$("#menutoggle").on("click", function() { | ||||||
|  | 		if ($('.navbar').is(":hidden")) { | ||||||
|  | 			$('.navbar').show(); | ||||||
|  | 			$('#dxtabs').show(); | ||||||
|  | 			$('#dxtitle').show(); | ||||||
|  | 			$('#menutoggle_i').removeClass('fa-arrow-down'); | ||||||
|  | 			$('#menutoggle_i').addClass('fa-arrow-up'); | ||||||
|  | 		} else { | ||||||
|  | 			$('.navbar').hide(); | ||||||
|  | 			$('#dxtabs').hide(); | ||||||
|  | 			$('#dxtitle').hide(); | ||||||
|  | 			$('#menutoggle_i').removeClass('fa-arrow-up'); | ||||||
|  | 			$('#menutoggle_i').addClass('fa-arrow-down'); | ||||||
|  | 		} | ||||||
|  | 	}); | ||||||
|  | 	 | ||||||
|  | 	var updateFromCAT = function() { | ||||||
|  | 	if($('select.radios option:selected').val() != '0') { | ||||||
|  | 		radioID = $('select.radios option:selected').val(); | ||||||
|  | 		$.getJSON( base_url+"radio/json/" + radioID, function( data ) { | ||||||
|  | 
 | ||||||
|  | 			if (data.error) { | ||||||
|  | 				if (data.error == 'not_logged_in') { | ||||||
|  | 					$(".radio_cat_state" ).remove(); | ||||||
|  | 					if($('.radio_login_error').length == 0) { | ||||||
|  | 						$('.messages').prepend('<div class="alert alert-danger radio_login_error" role="alert"><i class="fas fa-broadcast-tower"></i> You\'re not logged it. Please <a href="'+base_url+'">login</a></div>'); | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 				// Put future Errorhandling here
 | ||||||
|  | 			} else { | ||||||
|  | 				if($('.radio_login_error').length != 0) { | ||||||
|  | 					$(".radio_login_error" ).remove(); | ||||||
|  | 				} | ||||||
|  | 				var band = frequencyToBand(data.frequency); | ||||||
|  | 
 | ||||||
|  | 				if (band !== $("#band").val()) { | ||||||
|  | 					$("#band").val(band); | ||||||
|  | 					$("#band").trigger("change"); | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				var minutes = Math.floor(cat_timeout_interval / 60); | ||||||
|  | 
 | ||||||
|  | 				if(data.updated_minutes_ago > minutes) { | ||||||
|  | 					$(".radio_cat_state" ).remove(); | ||||||
|  | 					if($('.radio_timeout_error').length == 0) { | ||||||
|  | 						$('.messages').prepend('<div class="alert alert-danger radio_timeout_error" role="alert"><i class="fas fa-broadcast-tower"></i> Radio connection timed-out: ' + $('select.radios option:selected').text() + ' data is ' + data.updated_minutes_ago + ' minutes old.</div>'); | ||||||
|  | 					} else { | ||||||
|  | 						$('.radio_timeout_error').html('Radio connection timed-out: ' + $('select.radios option:selected').text() + ' data is ' + data.updated_minutes_ago + ' minutes old.'); | ||||||
|  | 					} | ||||||
|  | 				} else { | ||||||
|  | 					$(".radio_timeout_error" ).remove(); | ||||||
|  | 					text = '<i class="fas fa-broadcast-tower"></i><span style="margin-left:10px;"></span><b>TX:</b> '+(Math.round(parseInt(data.frequency)/100)/10000).toFixed(4)+' MHz'; | ||||||
|  | 					highlight_current_qrg((parseInt(data.frequency))/1000); | ||||||
|  | 					if(data.mode != null) { | ||||||
|  | 						text = text+'<span style="margin-left:10px"></span>'+data.mode; | ||||||
|  | 					} | ||||||
|  | 					if(data.power != null && data.power != 0) { | ||||||
|  | 						text = text+'<span style="margin-left:10px"></span>'+data.power+' W'; | ||||||
|  | 					} | ||||||
|  | 					if (! $('#radio_cat_state').length) { | ||||||
|  | 						$('.messages').prepend('<div aria-hidden="true"><div id="radio_cat_state" class="alert alert-success radio_cat_state" role="alert">'+text+'</div></div>'); | ||||||
|  | 					} else { | ||||||
|  | 						$('#radio_cat_state').html(text); | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		}); | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | $.fn.dataTable.moment(custom_date_format + ' HH:mm'); | ||||||
|  | // Update frequency every three second
 | ||||||
|  | setInterval(updateFromCAT, 3000); | ||||||
|  | 
 | ||||||
|  | // If a radios selected from drop down select radio update.
 | ||||||
|  | $('.radios').change(updateFromCAT); | ||||||
|  | 
 | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
							
								
								
									
										270
									
								
								src/Dxcc/Dxcc.php
									
									
									
									
									
										普通文件
									
								
							
							
						
						
									
										270
									
								
								src/Dxcc/Dxcc.php
									
									
									
									
									
										普通文件
									
								
							|  | @ -0,0 +1,270 @@ | ||||||
|  | <?php | ||||||
|  | 
 | ||||||
|  | namespace Cloudlog\Dxcc; | ||||||
|  | 
 | ||||||
|  | class Dxcc { | ||||||
|  | 	protected $dxcc = array(); | ||||||
|  | 	protected $dxccexceptions = array(); | ||||||
|  | 
 | ||||||
|  | 	function __construct($date) | ||||||
|  | 	{ | ||||||
|  | 		$this->read_data($date); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public function dxcc_lookup($call, $date) { | ||||||
|  | 
 | ||||||
|  | 		$csadditions = '/^P$|^R$|^A$|^M$/'; | ||||||
|  | 		$CI =& get_instance(); | ||||||
|  | 
 | ||||||
|  | 		if (array_key_exists($call, $this->dxccexceptions)) { | ||||||
|  | 			return $this->dxccexceptions[$call]; | ||||||
|  |         } else { | ||||||
|  | 
 | ||||||
|  | 			if (preg_match('/(^KG4)[A-Z09]{3}/', $call)) {       // KG4/ and KG4 5 char calls are Guantanamo Bay. If 4 or 6 char, it is USA
 | ||||||
|  | 				$call = "K"; | ||||||
|  | 			} elseif (preg_match('/(^OH\/)|(\/OH[1-9]?$)/', $call)) {   # non-Aland prefix!
 | ||||||
|  | 				$call = "OH";                                             # make callsign OH = finland
 | ||||||
|  | 			} elseif (preg_match('/(^CX\/)|(\/CX[1-9]?$)/', $call)) {   # non-Antarctica prefix!
 | ||||||
|  | 				$call = "CX";                                             # make callsign CX = Uruguay
 | ||||||
|  | 			} elseif (preg_match('/(^3D2R)|(^3D2.+\/R)/', $call)) {     # seems to be from Rotuma
 | ||||||
|  | 				$call = "3D2/R";                                          # will match with Rotuma
 | ||||||
|  | 			} elseif (preg_match('/^3D2C/', $call)) {                   # seems to be from Conway Reef
 | ||||||
|  | 				$call = "3D2/C";                                          # will match with Conway
 | ||||||
|  | 			} elseif (preg_match('/(^LZ\/)|(\/LZ[1-9]?$)/', $call)) {   # LZ/ is LZ0 by DXCC but this is VP8h
 | ||||||
|  | 				$call = "LZ"; | ||||||
|  | 			} elseif (preg_match('/(^KG4)[A-Z09]{2}/', $call)) { | ||||||
|  | 				$call = "KG4"; | ||||||
|  | 			} elseif (preg_match('/(^KG4)[A-Z09]{1}/', $call)) { | ||||||
|  | 				$call = "K"; | ||||||
|  | 			} elseif (preg_match('/\w\/\w/', $call)) { | ||||||
|  | 				if (preg_match_all('/^((\d|[A-Z])+\/)?((\d|[A-Z]){3,})(\/(\d|[A-Z])+)?(\/(\d|[A-Z])+)?$/', $call, $matches)) { | ||||||
|  | 					$prefix = $matches[1][0]; | ||||||
|  | 					$callsign = $matches[3][0]; | ||||||
|  | 					$suffix = $matches[5][0]; | ||||||
|  | 					if ($prefix) { | ||||||
|  | 						$prefix = substr($prefix, 0, -1); # Remove the / at the end
 | ||||||
|  | 					} | ||||||
|  | 					if ($suffix) { | ||||||
|  | 						$suffix = substr($suffix, 1); # Remove the / at the beginning
 | ||||||
|  | 					}; | ||||||
|  | 					if (preg_match($csadditions, $suffix)) { | ||||||
|  | 						if ($prefix) { | ||||||
|  | 							$call = $prefix; | ||||||
|  | 						} else { | ||||||
|  | 							$call = $callsign; | ||||||
|  | 						} | ||||||
|  | 					} else { | ||||||
|  | 						$result = $this->wpx($call, 1);                       # use the wpx prefix instead
 | ||||||
|  | 						if ($result == '') { | ||||||
|  | 							$row['adif'] = 0; | ||||||
|  | 							$row['entity'] = '- NONE -'; | ||||||
|  | 							$row['cqz'] = 0; | ||||||
|  | 							$row['long'] = '0'; | ||||||
|  | 							$row['lat'] = '0'; | ||||||
|  | 							return $row; | ||||||
|  | 						} else { | ||||||
|  | 							$call = $result . "AA"; | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			$len = strlen($call); | ||||||
|  | 
 | ||||||
|  | 			// query the table, removing a character from the right until a match
 | ||||||
|  | 			for ($i = $len; $i > 0; $i--){ | ||||||
|  | 				$result = ''; | ||||||
|  | 
 | ||||||
|  | 				if (array_key_exists(substr($call, 0, $i), $this->dxcc)) { | ||||||
|  | 					return $this->dxcc[substr($call, 0, $i)]; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		return array("Not Found", "Not Found"); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	function wpx($testcall, $i) { | ||||||
|  | 		$prefix = ''; | ||||||
|  | 		$a = ''; | ||||||
|  | 		$b = ''; | ||||||
|  | 		$c = ''; | ||||||
|  | 
 | ||||||
|  | 		$lidadditions = '/^QRP$|^LGT$/'; | ||||||
|  | 		$csadditions = '/^P$|^R$|^A$|^M$|^LH$/'; | ||||||
|  | 		$noneadditions = '/^MM$|^AM$/'; | ||||||
|  | 
 | ||||||
|  | 		# First check if the call is in the proper format, A/B/C where A and C
 | ||||||
|  | 		# are optional (prefix of guest country and P, MM, AM etc) and B is the
 | ||||||
|  | 		# callsign. Only letters, figures and "/" is accepted, no further check if the
 | ||||||
|  | 		# callsign "makes sense".
 | ||||||
|  | 		# 23.Apr.06: Added another "/X" to the regex, for calls like RV0AL/0/P
 | ||||||
|  | 		# as used by RDA-DXpeditions....
 | ||||||
|  | 
 | ||||||
|  | 		if (preg_match_all('/^((\d|[A-Z])+\/)?((\d|[A-Z]){3,})(\/(\d|[A-Z])+)?(\/(\d|[A-Z])+)?$/', $testcall, $matches)) { | ||||||
|  | 
 | ||||||
|  | 			# Now $1 holds A (incl /), $3 holds the callsign B and $5 has C
 | ||||||
|  | 			# We save them to $a, $b and $c respectively to ensure they won't get
 | ||||||
|  | 			# lost in further Regex evaluations.
 | ||||||
|  | 			$a = $matches[1][0]; | ||||||
|  | 			$b = $matches[3][0]; | ||||||
|  | 			$c = $matches[5][0]; | ||||||
|  | 
 | ||||||
|  | 			if ($a) { | ||||||
|  | 				$a = substr($a, 0, -1); # Remove the / at the end
 | ||||||
|  | 			} | ||||||
|  | 			if ($c) { | ||||||
|  | 				$c = substr($c, 1); # Remove the / at the beginning
 | ||||||
|  | 			}; | ||||||
|  | 
 | ||||||
|  | 			# In some cases when there is no part A but B and C, and C is longer than 2
 | ||||||
|  | 			# letters, it happens that $a and $b get the values that $b and $c should
 | ||||||
|  | 			# have. This often happens with liddish callsign-additions like /QRP and
 | ||||||
|  | 			# /LGT, but also with calls like DJ1YFK/KP5. ~/.yfklog has a line called
 | ||||||
|  | 			# "lidadditions", which has QRP and LGT as defaults. This sorts out half of
 | ||||||
|  | 			# the problem, but not calls like DJ1YFK/KH5. This is tested in a second
 | ||||||
|  | 			# try: $a looks like a call (.\d[A-Z]) and $b doesn't (.\d), they are
 | ||||||
|  | 			# swapped. This still does not properly handle calls like DJ1YFK/KH7K where
 | ||||||
|  | 			# only the OP's experience says that it's DJ1YFK on KH7K.
 | ||||||
|  | 			if (!$c && $a && $b) {                          # $a and $b exist, no $c
 | ||||||
|  | 				if (preg_match($lidadditions, $b)) {        # check if $b is a lid-addition
 | ||||||
|  | 					$b = $a; | ||||||
|  | 					$a = null;                              # $a goes to $b, delete lid-add
 | ||||||
|  | 				} elseif ((preg_match('/\d[A-Z]+$/', $a)) && (preg_match('/\d$/', $b))) {   # check for call in $a
 | ||||||
|  | 					$temp = $b; | ||||||
|  | 					$b = $a; | ||||||
|  | 					$a = $temp; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			# *** Added later ***  The check didn't make sure that the callsign
 | ||||||
|  | 			# contains a letter. there are letter-only callsigns like RAEM, but not
 | ||||||
|  | 			# figure-only calls.
 | ||||||
|  | 
 | ||||||
|  | 			if (preg_match('/^[0-9]+$/', $b)) {            # Callsign only consists of numbers. Bad!
 | ||||||
|  | 				return null;            # exit, undef
 | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			# Depending on these values we have to determine the prefix.
 | ||||||
|  | 			# Following cases are possible:
 | ||||||
|  | 			#
 | ||||||
|  | 			# 1.    $a and $c undef --> only callsign, subcases
 | ||||||
|  | 			# 1.1   $b contains a number -> everything from start to number
 | ||||||
|  | 			# 1.2   $b contains no number -> first two letters plus 0
 | ||||||
|  | 			# 2.    $a undef, subcases:
 | ||||||
|  | 			# 2.1   $c is only a number -> $a with changed number
 | ||||||
|  | 			# 2.2   $c is /P,/M,/MM,/AM -> 1.
 | ||||||
|  | 			# 2.3   $c is something else and will be interpreted as a Prefix
 | ||||||
|  | 			# 3.    $a is defined, will be taken as PFX, regardless of $c
 | ||||||
|  | 
 | ||||||
|  | 			if (($a == null) && ($c == null)) {                     # Case 1
 | ||||||
|  | 				if (preg_match('/\d/', $b)) {                       # Case 1.1, contains number
 | ||||||
|  | 					preg_match('/(.+\d)[A-Z]*/', $b, $matches);     # Prefix is all but the last
 | ||||||
|  | 					$prefix = $matches[1];                          # Letters
 | ||||||
|  | 				} else {                                            # Case 1.2, no number
 | ||||||
|  | 					$prefix = substr($b, 0, 2) . "0";               # first two + 0
 | ||||||
|  | 				} | ||||||
|  | 			} elseif (($a == null) && (isset($c))) {                # Case 2, CALL/X
 | ||||||
|  | 				if (preg_match('/^(\d)/', $c)) {                    # Case 2.1, number
 | ||||||
|  | 					preg_match('/(.+\d)[A-Z]*/', $b, $matches);     # regular Prefix in $1
 | ||||||
|  | 					# Here we need to find out how many digits there are in the
 | ||||||
|  | 					# prefix, because for example A45XR/0 is A40. If there are 2
 | ||||||
|  | 					# numbers, the first is not deleted. If course in exotic cases
 | ||||||
|  | 					# like N66A/7 -> N7 this brings the wrong result of N67, but I
 | ||||||
|  | 					# think that's rather irrelevant cos such calls rarely appear
 | ||||||
|  | 					# and if they do, it's very unlikely for them to have a number
 | ||||||
|  | 					# attached.   You can still edit it by hand anyway..
 | ||||||
|  | 					if (preg_match('/^([A-Z]\d)\d$/', $matches[1])) {        # e.g. A45   $c = 0
 | ||||||
|  | 						$prefix = $matches[1] . $c;  # ->   A40
 | ||||||
|  | 					} else {                         # Otherwise cut all numbers
 | ||||||
|  | 						preg_match('/(.*[A-Z])\d+/', $matches[1], $match); # Prefix w/o number in $1
 | ||||||
|  | 						$prefix = $match[1] . $c; # Add attached number
 | ||||||
|  | 					} | ||||||
|  | 				} elseif (preg_match($csadditions, $c)) { | ||||||
|  | 					preg_match('/(.+\d)[A-Z]*/', $b, $matches);     # Known attachment -> like Case 1.1
 | ||||||
|  | 					$prefix = $matches[1]; | ||||||
|  | 				} elseif (preg_match($noneadditions, $c)) { | ||||||
|  | 					return ''; | ||||||
|  | 				} elseif (preg_match('/^\d\d+$/', $c)) {            # more than 2 numbers -> ignore
 | ||||||
|  | 					preg_match('/(.+\d)[A-Z]* /', $b, $matches);    # see above
 | ||||||
|  | 					$prefix = $matches[1][0]; | ||||||
|  | 				} else {                                            # Must be a Prefix!
 | ||||||
|  | 					if (preg_match('/\d$/', $c)) {                  # ends in number -> good prefix
 | ||||||
|  | 						$prefix = $c; | ||||||
|  | 					} else {                                        # Add Zero at the end
 | ||||||
|  | 						$prefix = $c . "0"; | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} elseif (($a) && (preg_match($noneadditions, $c))) {                # Case 2.1, X/CALL/X ie TF/DL2NWK/MM - DXCC none
 | ||||||
|  | 			return ''; | ||||||
|  | 			} elseif ($a) { | ||||||
|  | 				# $a contains the prefix we want
 | ||||||
|  | 				if (preg_match('/\d$/', $a)) {                      # ends in number -> good prefix
 | ||||||
|  | 					$prefix = $a; | ||||||
|  | 				} else {                                            # add zero if no number
 | ||||||
|  | 					$prefix = $a . "0"; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			# In very rare cases (right now I can only think of KH5K and KH7K and FRxG/T
 | ||||||
|  | 			# etc), the prefix is wrong, for example KH5K/DJ1YFK would be KH5K0. In this
 | ||||||
|  | 			# case, the superfluous part will be cropped. Since this, however, changes the
 | ||||||
|  | 			# DXCC of the prefix, this will NOT happen when invoked from with an
 | ||||||
|  | 			# extra parameter $_[1]; this will happen when invoking it from &dxcc.
 | ||||||
|  | 
 | ||||||
|  | 			if (preg_match('/(\w+\d)[A-Z]+\d/', $prefix, $matches) && $i == null) { | ||||||
|  | 				$prefix = $matches[1][0]; | ||||||
|  | 			} | ||||||
|  | 			return $prefix; | ||||||
|  | 		} else { | ||||||
|  | 			return ''; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	  /* | ||||||
|  |     * Read cty.dat from AD1C | ||||||
|  |     */ | ||||||
|  |     function read_data($date) { | ||||||
|  | 		$CI =& get_instance(); | ||||||
|  | 		$dxcc_exceptions = $CI->db->select('`entity`, `adif`, `cqz`, `start`, `end`, `call`, `cont`, `long`, `lat`') | ||||||
|  | 		->where('(start <= ', $date) | ||||||
|  | 		->or_where('start is null)', NULL, false) | ||||||
|  | 		->where('(end >= ', $date) | ||||||
|  | 		->or_where('end is null)', NULL, false) | ||||||
|  | 		->get('dxcc_exceptions'); | ||||||
|  | 
 | ||||||
|  | 		if ($dxcc_exceptions->num_rows() > 0){ | ||||||
|  | 			foreach ($dxcc_exceptions->result() as $dxcce) { | ||||||
|  | 				$this->dxccexceptions[$dxcce->call]['adif'] = $dxcce->adif; | ||||||
|  | 				$this->dxccexceptions[$dxcce->call]['cont'] = $dxcce->cont; | ||||||
|  | 				$this->dxccexceptions[$dxcce->call]['entity'] = $dxcce->entity; | ||||||
|  | 				$this->dxccexceptions[$dxcce->call]['cqz'] = $dxcce->cqz; | ||||||
|  | 				$this->dxccexceptions[$dxcce->call]['start'] = $dxcce->start; | ||||||
|  | 				$this->dxccexceptions[$dxcce->call]['end'] = $dxcce->end; | ||||||
|  | 				$this->dxccexceptions[$dxcce->call]['long'] = $dxcce->long; | ||||||
|  | 				$this->dxccexceptions[$dxcce->call]['lat'] = $dxcce->lat; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		$dxcc_result = $CI->db->select('*') | ||||||
|  | 		->where('(start <= ', $date) | ||||||
|  | 		->or_where("start is null)", NULL, false) | ||||||
|  | 		->where('(end >= ', $date) | ||||||
|  | 		->or_where("end is null)", NULL, false) | ||||||
|  | 		->get('dxcc_prefixes'); | ||||||
|  | 
 | ||||||
|  | 		if ($dxcc_result->num_rows() > 0){ | ||||||
|  | 			foreach ($dxcc_result->result() as $dx) { | ||||||
|  | 				$this->dxcc[$dx->call]['adif'] = $dx->adif; | ||||||
|  | 				$this->dxcc[$dx->call]['cont'] = $dx->cont; | ||||||
|  | 				$this->dxcc[$dx->call]['entity'] = $dx->entity; | ||||||
|  | 				$this->dxcc[$dx->call]['cqz'] = $dx->cqz; | ||||||
|  | 				$this->dxcc[$dx->call]['start'] = $dx->start; | ||||||
|  | 				$this->dxcc[$dx->call]['end'] = $dx->end; | ||||||
|  | 				$this->dxcc[$dx->call]['long'] = $dx->long; | ||||||
|  | 				$this->dxcc[$dx->call]['lat'] = $dx->lat; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
		正在加载…
	
		在新工单中引用