Merge pull request #2420 from AndreasK79/logbook_map
[Advanced Logbook] Added map that uses the same filters as the search
这个提交包含在:
		
						当前提交
						290e46b3f7
					
				
					共有  5 个文件被更改,包括 713 次插入 和 307 次删除
				
			
		|  | @ -233,4 +233,133 @@ class Logbookadvanced extends CI_Controller { | ||||||
|         $data['qslimages'] = $this->logbookadvanced_model->getQslsForQsoIds($cleanids); |         $data['qslimages'] = $this->logbookadvanced_model->getQslsForQsoIds($cleanids); | ||||||
|         $this->load->view('logbookadvanced/qslcarousel', $data); |         $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; | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -2,11 +2,8 @@ | ||||||
| use Cloudlog\QSLManager\QSO; | use Cloudlog\QSLManager\QSO; | ||||||
| 
 | 
 | ||||||
| class Logbookadvanced_model extends CI_Model { | class Logbookadvanced_model extends CI_Model { | ||||||
|   /* | 
 | ||||||
|    * @param array $searchCriteria | 	public function searchDb($searchCriteria) { | ||||||
|    * @return array |  | ||||||
|    */ |  | ||||||
|   public function searchQsos($searchCriteria) : array { |  | ||||||
| 		$conditions = []; | 		$conditions = []; | ||||||
| 		$binding = [$searchCriteria['user_id']]; | 		$binding = [$searchCriteria['user_id']]; | ||||||
| 
 | 
 | ||||||
|  | @ -202,6 +199,16 @@ class Logbookadvanced_model extends CI_Model { | ||||||
| 
 | 
 | ||||||
|         $results = $data->result('array'); |         $results = $data->result('array'); | ||||||
| 
 | 
 | ||||||
|  | 		return $results; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  |   /* | ||||||
|  |    * @param array $searchCriteria | ||||||
|  |    * @return array | ||||||
|  |    */ | ||||||
|  |   public function searchQsos($searchCriteria) : array { | ||||||
|  | 		$results = $this->searchDb($searchCriteria); | ||||||
|  | 
 | ||||||
|         $qsos = []; |         $qsos = []; | ||||||
|         foreach ($results as $data) { |         foreach ($results as $data) { | ||||||
|             $qsos[] = new QSO($data); |             $qsos[] = new QSO($data); | ||||||
|  |  | ||||||
|  | @ -1,11 +1,38 @@ | ||||||
| <script type="text/javascript"> | <script type="text/javascript"> | ||||||
|   /* | /* | ||||||
|  * |  * | ||||||
|  * Define custom date format |  * Define custom date format | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
|   var custom_date_format = "<?php echo $custom_date_format ?>"; | var custom_date_format = "<?php echo $custom_date_format ?>"; | ||||||
| </script> | </script> | ||||||
|  | <style> | ||||||
|  | /*Legend specific*/ | ||||||
|  | .legend { | ||||||
|  |   padding: 6px 8px; | ||||||
|  |   font: 14px Arial, Helvetica, sans-serif; | ||||||
|  |   background: white; | ||||||
|  |   line-height: 24px; | ||||||
|  |   color: #555;
 | ||||||
|  |   border-radius: 10px; | ||||||
|  | } | ||||||
|  | .legend h4 { | ||||||
|  |   text-align: center; | ||||||
|  |   font-size: 16px; | ||||||
|  |   margin: 2px 12px 8px; | ||||||
|  |   color: #777;
 | ||||||
|  | } | ||||||
|  | .legend span { | ||||||
|  |   position: relative; | ||||||
|  |   bottom: 3px; | ||||||
|  | } | ||||||
|  | .legend i { | ||||||
|  |   width: 18px; | ||||||
|  |   height: 18px; | ||||||
|  |   float: left; | ||||||
|  |   margin: 0 8px 0 0; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| 
 | 
 | ||||||
| <div class="container-fluid qso_manager pt-3 pl-4 pr-4"> | <div class="container-fluid qso_manager pt-3 pl-4 pr-4"> | ||||||
|     <?php if ($this->session->flashdata('message')) { ?>
 |     <?php if ($this->session->flashdata('message')) { ?>
 | ||||||
|  | @ -14,15 +41,17 @@ | ||||||
|         <p><?php echo $this->session->flashdata('message'); ?></p>
 |         <p><?php echo $this->session->flashdata('message'); ?></p>
 | ||||||
|     </div> |     </div> | ||||||
|     <?php } ?>
 |     <?php } ?>
 | ||||||
| <div class="row"> |     <div class="row"> | ||||||
| 
 | 
 | ||||||
| 	<form id="searchForm" name="searchForm" action="<?php echo base_url()."index.php/logbookadvanced/search";?>" method="post"> |         <form id="searchForm" name="searchForm" action="<?php echo base_url()."index.php/logbookadvanced/search";?>" | ||||||
|  |             method="post"> | ||||||
|             <div class="filterbody collapse"> |             <div class="filterbody collapse"> | ||||||
|                 <div class="form-row"> |                 <div class="form-row"> | ||||||
|                     <div class="form-group col-lg-2 col-md-2 col-sm-3 col-xl"> |                     <div class="form-group col-lg-2 col-md-2 col-sm-3 col-xl"> | ||||||
|                         <label class="form-label" for="dateFrom">From</label> |                         <label class="form-label" for="dateFrom">From</label> | ||||||
|                         <div class="input-group input-group-sm date" id="dateFrom" data-target-input="nearest"> |                         <div class="input-group input-group-sm date" id="dateFrom" data-target-input="nearest"> | ||||||
| 					<input name="dateFrom" type="text" placeholder="<?php echo $datePlaceholder;?>" class="form-control" data-target="#dateFrom"/> |                             <input name="dateFrom" type="text" placeholder="<?php echo $datePlaceholder;?>" | ||||||
|  |                                 class="form-control" data-target="#dateFrom" /> | ||||||
|                             <div class="input-group-append" data-target="#dateFrom" data-toggle="datetimepicker"> |                             <div class="input-group-append" data-target="#dateFrom" data-toggle="datetimepicker"> | ||||||
|                                 <div class="input-group-text"><i class="fa fa-calendar"></i></div> |                                 <div class="input-group-text"><i class="fa fa-calendar"></i></div> | ||||||
|                             </div> |                             </div> | ||||||
|  | @ -31,7 +60,8 @@ | ||||||
|                     <div class="form-group col-lg-2 col-md-2 col-sm-3 col-xl"> |                     <div class="form-group col-lg-2 col-md-2 col-sm-3 col-xl"> | ||||||
|                         <label for="dateTo">To</label> |                         <label for="dateTo">To</label> | ||||||
|                         <div class="input-group input-group-sm date" id="dateTo" data-target-input="nearest"> |                         <div class="input-group input-group-sm date" id="dateTo" data-target-input="nearest"> | ||||||
| 					<input name="dateTo" type="text" placeholder="<?php echo $datePlaceholder;?>" class="form-control" data-target="#dateTo"/> |                             <input name="dateTo" type="text" placeholder="<?php echo $datePlaceholder;?>" | ||||||
|  |                                 class="form-control" data-target="#dateTo" /> | ||||||
|                             <div class="input-group-append" data-target="#dateTo" data-toggle="datetimepicker"> |                             <div class="input-group-append" data-target="#dateTo" data-toggle="datetimepicker"> | ||||||
|                                 <div class="input-group-text"><i class="fa fa-calendar"></i></div> |                                 <div class="input-group-text"><i class="fa fa-calendar"></i></div> | ||||||
|                             </div> |                             </div> | ||||||
|  | @ -72,7 +102,7 @@ | ||||||
|                     <div class="form-group col-lg-2 col-md-2 col-sm-3 col-xl"> |                     <div class="form-group col-lg-2 col-md-2 col-sm-3 col-xl"> | ||||||
|                         <label class="form-label" for="iota">IOTA</label> |                         <label class="form-label" for="iota">IOTA</label> | ||||||
|                         <select class="form-control form-control-sm" id="iota" name="iota"> |                         <select class="form-control form-control-sm" id="iota" name="iota"> | ||||||
| 					<option value ="">-</option> |                             <option value="">-</option> | ||||||
|                             <?php |                             <?php | ||||||
| 					foreach($iotaarray as $iota){ | 					foreach($iotaarray as $iota){ | ||||||
| 						echo '<option value=' . $iota->tag; | 						echo '<option value=' . $iota->tag; | ||||||
|  | @ -87,7 +117,8 @@ | ||||||
|                     </div> |                     </div> | ||||||
|                     <div class="form-group col-lg-2 col-md-2 col-sm-3 col-xl"> |                     <div class="form-group col-lg-2 col-md-2 col-sm-3 col-xl"> | ||||||
|                         <label class="form-label" for="gridsquare">Gridsquare</label> |                         <label class="form-label" for="gridsquare">Gridsquare</label> | ||||||
| 				<input type="text" name="gridsquare" id="gridsquare" class="form-control form-control-sm" value=""> |                         <input type="text" name="gridsquare" id="gridsquare" class="form-control form-control-sm" | ||||||
|  |                             value=""> | ||||||
|                     </div> |                     </div> | ||||||
|                     <div class="form-group col-lg-2 col-md-2 col-sm-3 col-xl"> |                     <div class="form-group col-lg-2 col-md-2 col-sm-3 col-xl"> | ||||||
|                         <label class="form-label" for="mode">Mode</label> |                         <label class="form-label" for="mode">Mode</label> | ||||||
|  | @ -169,6 +200,9 @@ | ||||||
|                         <input type="text" name="pota" id="pota" class="form-control form-control-sm" value=""> |                         <input type="text" name="pota" id="pota" class="form-control form-control-sm" value=""> | ||||||
|                     </div> |                     </div> | ||||||
|                 </div> |                 </div> | ||||||
|  |             </div> | ||||||
|  |     </div> | ||||||
|  |     <div class="qslfilterbody collapse"> | ||||||
|         <div class="form-row"> |         <div class="form-row"> | ||||||
|             <div class="form-group col-lg-2 col-md-2 col-sm-3 col-xl"> |             <div class="form-group col-lg-2 col-md-2 col-sm-3 col-xl"> | ||||||
|                 <label for="qslSent">QSL Sent</label> |                 <label for="qslSent">QSL Sent</label> | ||||||
|  | @ -261,7 +295,8 @@ | ||||||
|     <div class="actionbody collapse"> |     <div class="actionbody collapse"> | ||||||
|         <div class="mb-2 btn-group"> |         <div class="mb-2 btn-group"> | ||||||
|             <span class="h6 mr-1">With selected:</span> |             <span class="h6 mr-1">With selected:</span> | ||||||
| 			<button type="button" class="btn btn-sm btn-primary mr-1" id="btnUpdateFromCallbook">Update from Callbook</button> |             <button type="button" class="btn btn-sm btn-primary mr-1" id="btnUpdateFromCallbook">Update from | ||||||
|  |                 Callbook</button> | ||||||
|             <button type="button" class="btn btn-sm btn-primary mr-1" id="queueBureau">Queue Bureau</button> |             <button type="button" class="btn btn-sm btn-primary mr-1" id="queueBureau">Queue Bureau</button> | ||||||
|             <button type="button" class="btn btn-sm btn-primary mr-1" id="queueDirect">Queue Direct</button> |             <button type="button" class="btn btn-sm btn-primary mr-1" id="queueDirect">Queue Direct</button> | ||||||
|             <button type="button" class="btn btn-sm btn-primary mr-1" id="queueElectronic">Queue Electronic</button> |             <button type="button" class="btn btn-sm btn-primary mr-1" id="queueElectronic">Queue Electronic</button> | ||||||
|  | @ -294,12 +329,16 @@ | ||||||
|             <button type="button" class="btn btn-sm btn-primary mr-1" id="searchPota">Search POTA</button> |             <button type="button" class="btn btn-sm btn-primary mr-1" id="searchPota">Search POTA</button> | ||||||
|         </div> |         </div> | ||||||
|     </div> |     </div> | ||||||
| </div> |  | ||||||
| <div class="form-row pt-2"> | <div class="form-row pt-2"> | ||||||
| <div class="form-group form-inline col-lg d-flex flex-row justify-content-center align-items-center"> |     <div class="form-group form-inline col-lg d-flex flex-row justify-content-center align-items-center"> | ||||||
| 	<button type="button" class="btn btn-sm btn-primary mr-1" data-toggle="collapse" data-target=".quickfilterbody">Quickfilters</button> |         <button type="button" class="btn btn-sm btn-primary mr-1" data-toggle="collapse" | ||||||
| 	<button type="button" class="btn btn-sm btn-primary mr-1" data-toggle="collapse" data-target=".filterbody">Filters</button> |             data-target=".quickfilterbody">Quickfilters</button> | ||||||
| 	<button type="button" class="btn btn-sm btn-primary mr-1" data-toggle="collapse" data-target=".actionbody">Actions</button> |         <button type="button" class="btn btn-sm btn-primary mr-1" data-toggle="collapse" | ||||||
|  |             data-target=".qslfilterbody">QSL Filters</button> | ||||||
|  |         <button type="button" class="btn btn-sm btn-primary mr-1" data-toggle="collapse" | ||||||
|  |             data-target=".filterbody">Filters</button> | ||||||
|  |         <button type="button" class="btn btn-sm btn-primary mr-1" data-toggle="collapse" | ||||||
|  |             data-target=".actionbody">Actions</button> | ||||||
|         <label for="qsoResults" class="mr-2"># Results</label>
 |         <label for="qsoResults" class="mr-2"># Results</label>
 | ||||||
|         <select id="qsoResults" name="qsoResults" class="form-control form-control-sm mr-2"> |         <select id="qsoResults" name="qsoResults" class="form-control form-control-sm mr-2"> | ||||||
|             <option value="250">250</option> |             <option value="250">250</option> | ||||||
|  | @ -308,14 +347,20 @@ | ||||||
|             <option value="5000">5000</option> |             <option value="5000">5000</option> | ||||||
|         </select> |         </select> | ||||||
|         <button type="submit" class="btn btn-sm btn-primary mr-1" id="searchButton">Search</button> |         <button type="submit" class="btn btn-sm btn-primary mr-1" id="searchButton">Search</button> | ||||||
|  |         <button type="button" class="btn btn-sm btn-primary mr-1" id="mapButton" | ||||||
|  |             onclick="mapQsos(this.form);">Map</button> | ||||||
|         <button type="reset" class="btn btn-sm btn-danger mr-1" id="resetButton">Reset</button> |         <button type="reset" class="btn btn-sm btn-danger mr-1" id="resetButton">Reset</button> | ||||||
| </div> |  | ||||||
|     </div> |     </div> | ||||||
|  | </div> | ||||||
| </form> | </form> | ||||||
| 	<table style="width:100%" class="table-sm table table-bordered table-hover table-striped table-condensed text-center" id="qsoList"> | <table style="width:100%" class="table-sm table table-bordered table-hover table-striped table-condensed text-center" | ||||||
|  |     id="qsoList"> | ||||||
|     <thead> |     <thead> | ||||||
|         <tr> |         <tr> | ||||||
| 				<th><div class="form-check" style="margin-top: -1.5em"><input class="form-check-input" type="checkbox" id="checkBoxAll" /></div></th> |             <th> | ||||||
|  |                 <div class="form-check" style="margin-top: -1.5em"><input class="form-check-input" type="checkbox" | ||||||
|  |                         id="checkBoxAll" /></div> | ||||||
|  |             </th> | ||||||
|             <th>Date/Time</th> |             <th>Date/Time</th> | ||||||
|             <th>De</th> |             <th>De</th> | ||||||
|             <th>Dx</th> |             <th>Dx</th> | ||||||
|  | @ -343,5 +388,5 @@ | ||||||
|     </thead> |     </thead> | ||||||
|     <tbody> |     <tbody> | ||||||
|     </tbody> |     </tbody> | ||||||
| 	</table> | </table> | ||||||
| </div> | </div> | ||||||
|  |  | ||||||
|  | @ -517,6 +517,11 @@ div#station_logbooks_linked_table_paginate { | ||||||
|     margin-bottom: 0px; |     margin-bottom: 0px; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #advancedmap { | ||||||
|  | 	height: calc(100vh - 280px) !important; | ||||||
|  | 	max-height: 1000px !important; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .lotw-cert-list table { | .lotw-cert-list table { | ||||||
|     margin-bottom: 0px; |     margin-bottom: 0px; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -167,6 +167,17 @@ $(document).ready(function () { | ||||||
| 	}); | 	}); | ||||||
| 
 | 
 | ||||||
| 	$('#searchForm').submit(function (e) { | 	$('#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); | 		$('#searchButton').prop("disabled", true); | ||||||
| 
 | 
 | ||||||
| 		$.ajax({ | 		$.ajax({ | ||||||
|  | @ -675,3 +686,212 @@ 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('<div id="advancedmap"></div>'); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	$.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 © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors'; | ||||||
|  | 	// If map is already initialized
 | ||||||
|  | 	var container = L.DomUtil.get('advancedmap'); | ||||||
|  | 
 | ||||||
|  | 	if(container != null){ | ||||||
|  | 		container._leaflet_id = null; | ||||||
|  | 		container.remove(); | ||||||
|  | 		$(".qso_manager").append('<div id="advancedmap"></div>'); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var map = new L.Map('advancedmap', { | ||||||
|  | 		fullscreenControl: true, | ||||||
|  | 		fullscreenControlOptions: { | ||||||
|  | 			position: 'topleft' | ||||||
|  | 		}, | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	L.tileLayer( | ||||||
|  | 		osmUrl, | ||||||
|  | 		{ | ||||||
|  | 			attribution: '© <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>', | ||||||
|  | 			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 linecolor = 'blue'; | ||||||
|  | 
 | ||||||
|  | 	if (isDarkModeTheme()) { | ||||||
|  | 		linecolor = 'red'; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	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: linecolor, | ||||||
|  | 			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 += "<h4>" + counter + " QSOs plotted</h4>"; | ||||||
|  |         return div; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     legend.addTo(map); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 	function createContentMessage(qso) { | ||||||
|  | 		var table = '<table><tbody>' + | ||||||
|  | 		'<tr>' + | ||||||
|  | 		'<td>' + | ||||||
|  | 		'Station callsign: ' + qso.mycallsign + | ||||||
|  | 		"</td></tr>" + | ||||||
|  | 		'<tr>' + | ||||||
|  | 		'<td>' + | ||||||
|  | 		'Gridsquare: ' + qso.mygridsquare + | ||||||
|  | 		"</td></tr>"; | ||||||
|  | 		return (table += "</tbody></table>"); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	function createContentMessageDx(qso) { | ||||||
|  | 		var table = '<table><tbody>' + | ||||||
|  | 		'<tr>' + | ||||||
|  | 		'<td>Callsign</td>' + | ||||||
|  | 		'<td>' + qso.callsign + '</td>' + | ||||||
|  | 		'</tr>' + | ||||||
|  | 		'<tr>' + | ||||||
|  | 		'<td>Date/time</td>' + | ||||||
|  | 		'<td>' + qso.datetime + '</td>' + | ||||||
|  | 		'</tr>' + | ||||||
|  | 		'<tr>'; | ||||||
|  | 		if (qso.satname != "") { | ||||||
|  | 			table += '<td>Band</td>' + | ||||||
|  | 			'<td>' + qso.satname + '</td>' + | ||||||
|  | 			'</tr>' + | ||||||
|  | 			'<tr>'; | ||||||
|  | 		} else { | ||||||
|  | 			table += '<td>Band</td>' + | ||||||
|  | 			'<td>' + qso.band + '</td>' + | ||||||
|  | 			'</tr>' + | ||||||
|  | 			'<tr>'; | ||||||
|  | 		} | ||||||
|  | 		table += '<td>Mode</td>' + | ||||||
|  | 		'<td>' + qso.mode + '</td>' + | ||||||
|  | 		'</tr>' + | ||||||
|  | 		'<tr>'; | ||||||
|  | 		if (qso.gridsquare != undefined) { | ||||||
|  | 			table += '<td>Gridsquare</td>' + | ||||||
|  | 			'<td>' + qso.gridsquare + '</td>' + | ||||||
|  | 			'</tr>'; | ||||||
|  | 		} | ||||||
|  | 		if (qso.distance != undefined) { | ||||||
|  | 			table += '<td>Distance</td>' + | ||||||
|  | 			'<td>' + qso.distance + '</td>' + | ||||||
|  | 			'</tr>'; | ||||||
|  | 		} | ||||||
|  | 		if (qso.bearing != undefined) { | ||||||
|  | 			table += '<td>Bearing</td>' + | ||||||
|  | 			'<td>' + qso.bearing + '</td>' + | ||||||
|  | 			'</tr>'; | ||||||
|  | 		} | ||||||
|  | 		return (table += '</tbody></table>'); | ||||||
|  | 	} | ||||||
|  |  | ||||||
		正在加载…
	
		在新工单中引用