From 389d9fe06b59c88a940139a774e674b1a0165532 Mon Sep 17 00:00:00 2001 From: Andreas <6977712+AndreasK79@users.noreply.github.com> Date: Fri, 18 Aug 2023 20:02:47 +0200 Subject: [PATCH] [Advanced Logbook] Added map that uses the same filters as the search --- application/controllers/Logbookadvanced.php | 129 ++++ application/models/Logbookadvanced_model.php | 19 +- application/views/logbookadvanced/index.php | 647 ++++++++++--------- assets/css/general.css | 5 + assets/js/sections/logbookadvanced.js | 214 ++++++ 5 files changed, 707 insertions(+), 307 deletions(-) diff --git a/application/controllers/Logbookadvanced.php b/application/controllers/Logbookadvanced.php index f25fe68f..87a54e92 100644 --- a/application/controllers/Logbookadvanced.php +++ b/application/controllers/Logbookadvanced.php @@ -233,4 +233,133 @@ class Logbookadvanced extends CI_Controller { $data['qslimages'] = $this->logbookadvanced_model->getQslsForQsoIds($cleanids); $this->load->view('logbookadvanced/qslcarousel', $data); } + + public function mapQsos() { + $this->load->model('logbookadvanced_model'); + + $searchCriteria = array( + 'user_id' => (int)$this->session->userdata('user_id'), + 'dateFrom' => xss_clean($this->input->post('dateFrom')), + 'dateTo' => xss_clean($this->input->post('dateTo')), + 'de' => xss_clean($this->input->post('de')), + 'dx' => xss_clean($this->input->post('dx')), + 'mode' => xss_clean($this->input->post('mode')), + 'band' => xss_clean($this->input->post('band')), + 'qslSent' => xss_clean($this->input->post('qslSent')), + 'qslReceived' => xss_clean($this->input->post('qslReceived')), + 'iota' => xss_clean($this->input->post('iota')), + 'dxcc' => xss_clean($this->input->post('dxcc')), + 'propmode' => xss_clean($this->input->post('propmode')), + 'gridsquare' => xss_clean($this->input->post('gridsquare')), + 'state' => xss_clean($this->input->post('state')), + 'cqzone' => xss_clean($this->input->post('cqzone')), + 'qsoresults' => xss_clean($this->input->post('qsoresults')), + 'sats' => xss_clean($this->input->post('sats')), + 'lotwSent' => xss_clean($this->input->post('lotwSent')), + 'lotwReceived' => xss_clean($this->input->post('lotwReceived')), + 'eqslSent' => xss_clean($this->input->post('eqslSent')), + 'eqslReceived' => xss_clean($this->input->post('eqslReceived')), + 'qslvia' => xss_clean($this->input->post('qslvia')), + 'sota' => xss_clean($this->input->post('sota')), + 'pota' => xss_clean($this->input->post('pota')), + 'wwff' => xss_clean($this->input->post('wwff')), + 'qslimages' => xss_clean($this->input->post('qslimages')), + ); + + if ($this->session->userdata('user_measurement_base') == NULL) { + $measurement_base = $this->config->item('measurement_base'); + } + else { + $measurement_base = $this->session->userdata('user_measurement_base'); + } + + $CI =& get_instance(); + // Get Date format + if($CI->session->userdata('user_date_format')) { + // If Logged in and session exists + $custom_date_format = $CI->session->userdata('user_date_format'); + } else { + // Get Default date format from /config/cloudlog.php + $custom_date_format = $CI->config->item('qso_date_format'); + } + + switch ($measurement_base) { + case 'M': + $var_dist = " miles"; + break; + case 'N': + $var_dist = " nautic miles"; + break; + case 'K': + $var_dist = " kilometers"; + break; + } + + $mappedcoordinates = array(); + foreach ($this->logbookadvanced_model->searchDb($searchCriteria) as $qso) { + if (!empty($qso['COL_MY_GRIDSQUARE']) || !empty($qso['COL_MY_VUCC_GRIDS'])) { + if (!empty($qso['COL_GRIDSQUARE']) || !empty($qso['COL_VUCC_GRIDS'])) { + $mappedcoordinates[] = $this->calculate($qso, ($qso['COL_MY_GRIDSQUARE'] ?? '') == '' ? $qso['COL_MY_VUCC_GRIDS'] : $qso['COL_MY_GRIDSQUARE'], ($qso['COL_GRIDSQUARE'] ?? '') == '' ? $qso['COL_VUCC_GRIDS'] : $qso['COL_GRIDSQUARE'], $measurement_base, $var_dist, $custom_date_format); + } else { + if (!empty($qso['lat']) || !empty($qso['long'])) { + $mappedcoordinates[] = $this->calculateCoordinates($qso, $qso['lat'], $qso['long'], ($qso['COL_MY_GRIDSQUARE'] ?? '') == '' ? $qso['COL_MY_VUCC_GRIDS'] : $qso['COL_MY_GRIDSQUARE'], $measurement_base, $var_dist, $custom_date_format); + } + } + } + } + + header("Content-Type: application/json"); + print json_encode($mappedcoordinates); + } + + public function calculate($qso, $locator1, $locator2, $measurement_base, $var_dist, $custom_date_format) { + $this->load->library('Qra'); + + $data['distance'] = $this->qra->distance($locator1, $locator2, $measurement_base) . $var_dist; + $data['bearing'] = $this->qra->get_bearing($locator1, $locator2) . "º"; + $latlng1 = $this->qra->qra2latlong($locator1); + $latlng2 = $this->qra->qra2latlong($locator2); + $latlng1[0] = number_format((float)$latlng1[0], 3, '.', '');; + $latlng1[1] = number_format((float)$latlng1[1], 3, '.', '');; + $latlng2[0] = number_format((float)$latlng2[0], 3, '.', '');; + $latlng2[1] = number_format((float)$latlng2[1], 3, '.', '');; + + $data['latlng1'] = $latlng1; + $data['latlng2'] = $latlng2; + + $data['callsign'] = $qso['COL_CALL']; + $data['band'] = $qso['COL_BAND']; + $data['mode'] = $qso['COL_MODE']; + $data['gridsquare'] = $locator2; + $data['mygridsquare'] = $locator1; + $data['mycallsign'] = $qso['station_callsign']; + $data['datetime'] = date($custom_date_format, strtotime($qso['COL_TIME_ON'])). date(' H:i',strtotime($qso['COL_TIME_ON'])); + $data['satname'] = $qso['COL_SAT_NAME']; + + return $data; + } + + public function calculateCoordinates($qso, $lat, $long, $mygrid, $measurement_base, $var_dist, $custom_date_format) { + $this->load->library('Qra'); + + $latlng1 = $this->qra->qra2latlong($mygrid); + $latlng2[0] = $lat; + $latlng2[1] = $long; + $latlng1[0] = number_format((float)$latlng1[0], 3, '.', '');; + $latlng1[1] = number_format((float)$latlng1[1], 3, '.', '');; + $latlng2[0] = number_format((float)$latlng2[0], 3, '.', '');; + $latlng2[1] = number_format((float)$latlng2[1], 3, '.', '');; + + $data['latlng1'] = $latlng1; + $data['latlng2'] = $latlng2; + $data['callsign'] = $qso['COL_CALL']; + $data['band'] = $qso['COL_BAND']; + $data['mode'] = $qso['COL_MODE']; + $data['mygridsquare'] = $mygrid; + $data['mycallsign'] = $qso['station_callsign']; + $data['datetime'] = date($custom_date_format, strtotime($qso['COL_TIME_ON'])). date(' H:i',strtotime($qso['COL_TIME_ON'])); + $data['satname'] = $qso['COL_SAT_NAME']; + + return $data; + } } diff --git a/application/models/Logbookadvanced_model.php b/application/models/Logbookadvanced_model.php index de032084..988e574d 100644 --- a/application/models/Logbookadvanced_model.php +++ b/application/models/Logbookadvanced_model.php @@ -2,11 +2,8 @@ use Cloudlog\QSLManager\QSO; class Logbookadvanced_model extends CI_Model { - /* - * @param array $searchCriteria - * @return array - */ - public function searchQsos($searchCriteria) : array { + + public function searchDb($searchCriteria) { $conditions = []; $binding = [$searchCriteria['user_id']]; @@ -202,12 +199,22 @@ class Logbookadvanced_model extends CI_Model { $results = $data->result('array'); + return $results; + } + + /* + * @param array $searchCriteria + * @return array + */ + public function searchQsos($searchCriteria) : array { + $results = $this->searchDb($searchCriteria); + $qsos = []; foreach ($results as $data) { $qsos[] = new QSO($data); } - return $qsos; + return $qsos; } public function getQsosForAdif($ids, $user_id, $sortorder = null) : object { diff --git a/application/views/logbookadvanced/index.php b/application/views/logbookadvanced/index.php index 49d63ce3..bd7fee3b 100644 --- a/application/views/logbookadvanced/index.php +++ b/application/views/logbookadvanced/index.php @@ -1,63 +1,93 @@ +
- session->flashdata('message')) { ?> - -
-

session->flashdata('message'); ?>

-
- -
+ session->flashdata('message')) { ?> + +
+

session->flashdata('message'); ?>

+
+ +
-
" method="post"> -
-
-
- -
- -
-
-
-
-
-
- -
- -
-
-
-
-
-
- - +
+
+
+
+
+
+ +
+ +
+
+
+
+
+
+ + -
-
- - -
-
- - +
+
+ + -
-
- - + + tag; echo '>' . $iota->tag . ' - ' . $iota->name . ''; } ?> - -
-
- - -
-
- - -
-
- - +
+
+ + +
+
+ + -
-
- - + + - -
- -
- - -
-
- - + + + + + + + + + + + + + + + + + + + + +
+
+ + -
-
- - -
-
- - -
-
- - -
-
-
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - - - - - - - - -
-
- - -
-
-
+ ?> + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + + + + + + + + +
+
+ + +
+
+
-
-
- With selected: - - - - - - - - - - - - - - - -
-
-
-
- Quick search with selected: - - - - - - - - - - - -
-
- +
+
+ With selected: + + + + + + + + + + + + + + + +
+
+
+
+ Quick search with selected: + + + + + + + + + + + +
+
-
- - - - - - - +
+ + + + + + + + + +
-
- - - - - - - - - - - - - - - - - session->userdata('user_eqsl_name') != ""){ +
Date/TimeDeDxModeRST (S)RST (R)BandMy RefsRefsNameQSL ViaQSL
+ + + + + + + + + + + + + + + + session->userdata('user_eqsl_name') != ""){ echo ''; } ?> - session->userdata('user_lotw_name') != ""){ + session->userdata('user_lotw_name') != ""){ echo ''; } ?> - - - - - - - - - -
+
+
Date/TimeDeDxModeRST (S)RST (R)BandMy RefsRefsNameQSL ViaQSLeQSLLoTWQSL MsgDXCCStateCQ ZoneIOTA
+ QSL Msg + DXCC + State + CQ Zone + IOTA + + + + + diff --git a/assets/css/general.css b/assets/css/general.css index a4705e96..b9ad60e1 100644 --- a/assets/css/general.css +++ b/assets/css/general.css @@ -515,4 +515,9 @@ div#station_logbooks_linked_table_paginate { .previous-qsos table { margin-bottom: 0px; +} + +#advancedmap { + height: calc(100vh - 280px) !important; + max-height: 1000px !important; } \ No newline at end of file diff --git a/assets/js/sections/logbookadvanced.js b/assets/js/sections/logbookadvanced.js index 63f92de5..d91c4f98 100644 --- a/assets/js/sections/logbookadvanced.js +++ b/assets/js/sections/logbookadvanced.js @@ -167,6 +167,17 @@ $(document).ready(function () { }); $('#searchForm').submit(function (e) { + var container = L.DomUtil.get('advancedmap'); + + if(container != null){ + container._leaflet_id = null; + container.remove(); + } + + $("#qsoList").attr("Hidden", false); + $("#qsoList_wrapper").attr("Hidden", false); + $("#qsoList_info").attr("Hidden", false); + $('#searchButton').prop("disabled", true); $.ajax({ @@ -675,3 +686,206 @@ function printlabel() { }); } +function mapQsos(form) { + $('#mapButton').prop("disabled", true); + + $("#qsoList").attr("Hidden", true); + $("#qsoList_wrapper").attr("Hidden", true); + $("#qsoList_info").attr("Hidden", true); + + var amap = $('#advancedmap').val(); + if (amap == undefined) { + $(".qso_manager").append('
'); + } + + $.ajax({ + url: base_url + 'index.php/logbookadvanced/mapQsos', + type: 'post', + data: { + dateFrom: this.dateFrom.value, + dateTo: this.dateTo.value, + de: this.de.value, + dx: this.dx.value, + mode: this.mode.value, + band: this.band.value, + qslSent: this.qslSent.value, + qslReceived: this.qslReceived.value, + iota: this.iota.value, + dxcc: this.dxcc.value, + propmode: this.selectPropagation.value, + gridsquare: this.gridsquare.value, + state: this.state.value, + qsoresults: this.qsoResults.value, + sats: this.sats.value, + cqzone: this.cqzone.value, + lotwSent: this.lotwSent.value, + lotwReceived: this.lotwReceived.value, + eqslSent: this.eqslSent.value, + eqslReceived: this.eqslReceived.value, + qslvia: $('[name="qslviainput"]').val(), + sota: this.sota.value, + pota: this.pota.value, + wwff: this.wwff.value, + qslimages: this.qslimages.value, + }, + success: function(data) { + loadMap(data); + }, + error: function() { + $('#mapButton').prop("disabled", false); + }, + }); + +}; + +function loadMap(data) { + $('#mapButton').prop("disabled", false); + var osmUrl='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'; + var osmAttrib='Map data © OpenStreetMap contributors'; + // If map is already initialized + var container = L.DomUtil.get('advancedmap'); + + if(container != null){ + container._leaflet_id = null; + container.remove(); + $(".qso_manager").append('
'); + } + + var map = new L.Map('advancedmap', { + fullscreenControl: true, + fullscreenControlOptions: { + position: 'topleft' + }, + }); + + L.tileLayer( + osmUrl, + { + attribution: '© OpenStreetMap contributors, CC-BY-SA', + maxZoom: 18, + zoom: 3, + minZoom: 2, + } + ).addTo(map); + + map.setView([30, 0], 1.5); + + var maidenhead = L.maidenheadqrb().addTo(map); + + var osm = new L.TileLayer(osmUrl, {minZoom: 1, maxZoom: 9, attribution: osmAttrib}); + + map.addLayer(osm); + + var redIcon = L.icon({ + iconUrl: icon_dot_url, + iconSize: [10, 10], // size of the icon + }); + + var counter = 0; + + $.each(data, function(k, v) { + counter++; + // Need to fix so that marker is placed at same place as end of line, but this only needs to be done when longitude is < -170 + if (this.latlng2[1] < -170) { + this.latlng2[1] = parseFloat(this.latlng2[1])+360; + } + if (this.latlng1[1] < -170) { + this.latlng1[1] = parseFloat(this.latlng1[1])+360; + } + + var popupmessage = createContentMessage(this); + var popupmessage2 = createContentMessageDx(this); + + var marker = L.marker([this.latlng1[0], this.latlng1[1]], {icon: redIcon}, {closeOnClick: false, autoClose: false}).addTo(map).bindPopup(popupmessage); + marker.on('mouseover',function(ev) { + ev.target.openPopup(); + }); + + var marker2 = L.marker([this.latlng2[0], this.latlng2[1]], {icon: redIcon},{closeOnClick: false, autoClose: false}).addTo(map).bindPopup(popupmessage2);; + marker2.on('mouseover',function(ev) { + ev.target.openPopup(); + }); + + const multiplelines = []; + multiplelines.push( + new L.LatLng(this.latlng1[0], this.latlng1[1]), + new L.LatLng(this.latlng2[0], this.latlng2[1]) + ) + + const geodesic = L.geodesic(multiplelines, { + weight: 1, + opacity: 1, + color: 'red', + wrap: false, + steps: 100 + }).addTo(map); + }); + + /*Legend specific*/ + var legend = L.control({ position: "topright" }); + + legend.onAdd = function(map) { + var div = L.DomUtil.create("div", "legend"); + div.innerHTML += "

" + counter + " QSOs plotted

"; + return div; + }; + + legend.addTo(map); +} + + function createContentMessage(qso) { + var table = '' + + '' + + '" + + '' + + '"; + return (table += "
' + + 'Station callsign: ' + qso.mycallsign + + "
' + + 'Gridsquare: ' + qso.mygridsquare + + "
"); + } + + function createContentMessageDx(qso) { + var table = '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + ''; + if (qso.satname != "") { + table += '' + + '' + + '' + + ''; + } else { + table += '' + + '' + + '' + + ''; + } + table += '' + + '' + + '' + + ''; + if (qso.gridsquare != undefined) { + table += '' + + '' + + ''; + } + if (qso.distance != undefined) { + table += '' + + '' + + ''; + } + if (qso.bearing != undefined) { + table += '' + + '' + + ''; + } + return (table += '
Callsign' + qso.callsign + '
Date/time' + qso.datetime + '
Band' + qso.satname + '
Band' + qso.band + '
Mode' + qso.mode + '
Gridsquare' + qso.gridsquare + '
Distance' + qso.distance + '
Bearing' + qso.bearing + '
'); + }