kopia lustrzana https://github.com/magicbug/Cloudlog
Merge pull request #1494 from phl0/activatorsBeauty
Add map for activated grids by activatorspull/1518/head
commit
79f4657c82
|
@ -0,0 +1,30 @@
|
|||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
/*
|
||||
|
||||
Data lookup functions used within Cloudlog
|
||||
|
||||
*/
|
||||
class Activatorsmap 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'); }
|
||||
}
|
||||
|
||||
public function index() {
|
||||
$data['page_title'] = "Activators Map";
|
||||
|
||||
$this->load->model('stations');
|
||||
$data['station_locator'] = $this->stations->find_gridsquare();
|
||||
|
||||
$this->load->view('activatorsmap/index', $data);
|
||||
}
|
||||
|
||||
public function calculate() {
|
||||
$data['grids'] = "test";
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode($data);
|
||||
}
|
||||
}
|
|
@ -102,6 +102,7 @@ function write_activators($activators_array, $vucc_grids, $custom_date_format, $
|
|||
<td>Count</td>
|
||||
<td>Gridsquares</td>
|
||||
<td>Show QSOs</td>
|
||||
<td>Show Map</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>';
|
||||
|
@ -112,10 +113,16 @@ function write_activators($activators_array, $vucc_grids, $custom_date_format, $
|
|||
$grids = $line->grids;
|
||||
$count = $line->count;
|
||||
if (array_key_exists($line->call, $vucc_grids)) {
|
||||
$grids .= ','.$vucc_grids[$line->call];
|
||||
foreach(explode(',', $vucc_grids[$line->call]) as $vgrid) {
|
||||
if(!strpos($grids, $vgrid)) {
|
||||
$grids .= ','.$vgrid;
|
||||
}
|
||||
}
|
||||
$grids = str_replace(' ', '', $grids);
|
||||
$grid_array = explode(',', $grids);
|
||||
array_unique($grid_array, SORT_STRING);
|
||||
sort($grid_array);
|
||||
$count = count($grid_array);
|
||||
$grids = implode(', ', $grid_array);
|
||||
}
|
||||
array_push($activators, array($count, $call, $grids));
|
||||
}
|
||||
|
@ -126,7 +133,8 @@ function write_activators($activators_array, $vucc_grids, $custom_date_format, $
|
|||
<td>'.$line[1].'</td>
|
||||
<td>'.$line[0].'</td>
|
||||
<td style="text-align: left; font-family: monospace;">'.$line[2].'</td>
|
||||
<td><a href=javascript:displayActivatorsContacts("'.$line[1].'","'.$band.'","'.$leogeo.'")>Show</a></td>
|
||||
<td><a href=javascript:displayActivatorsContacts("'.$line[1].'","'.$band.'","'.$leogeo.'")><i class="fas fa-list"></i></a></td>
|
||||
<td><a href=javascript:spawnActivatorsMap("'.$line[1].'","'.$line[0].'","'.str_replace(' ', '', $line[2]).'")><i class="fas fa-globe"></i></a></td>
|
||||
</tr>';
|
||||
}
|
||||
echo '</tfoot></table></div>';
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
<div class="activatorsmapResult"></div>
|
||||
<div id="mapactivators" style="height: 500px"></div>
|
|
@ -6,6 +6,9 @@
|
|||
<script src="<?php echo base_url(); ?>assets/js/jquery.jclock.js"></script>
|
||||
<script type="text/javascript" src="<?php echo base_url(); ?>assets/js/leaflet/leaflet.js"></script>
|
||||
<script type="text/javascript" src="<?php echo base_url(); ?>assets/js/leaflet/L.Maidenhead.qrb.js"></script>
|
||||
<?php if ($this->uri->segment(1) == "activators") { ?>
|
||||
<script type="text/javascript" src="<?php echo base_url();?>assets/js/leaflet/L.Maidenhead.activators.js"></script>
|
||||
<?php } ?>
|
||||
<script type="text/javascript" src="<?php echo base_url(); ?>assets/js/leaflet/leaflet.geodesic.js"></script>
|
||||
<script type="text/javascript" src="<?php echo base_url() ;?>assets/js/radiohelpers.js"></script>
|
||||
<script type="text/javascript" src="<?php echo base_url() ;?>assets/js/darkmodehelpers.js"></script>
|
||||
|
@ -479,6 +482,31 @@ function spawnQrbCalculator(locator1, locator2) {
|
|||
});
|
||||
}
|
||||
|
||||
function spawnActivatorsMap(call, count, grids) {
|
||||
$.ajax({
|
||||
url: base_url + 'index.php/activatorsmap',
|
||||
type: 'post',
|
||||
success: function (html) {
|
||||
BootstrapDialog.show({
|
||||
title: 'Activators Map',
|
||||
size: BootstrapDialog.SIZE_WIDE,
|
||||
cssClass: 'lookup-dialog',
|
||||
nl2br: false,
|
||||
message: html,
|
||||
onshown: function(dialog) {
|
||||
showActivatorsMap(call, count, grids);
|
||||
},
|
||||
buttons: [{
|
||||
label: 'Close',
|
||||
action: function (dialogItself) {
|
||||
dialogItself.close();
|
||||
}
|
||||
}]
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function calculateQrb() {
|
||||
let locator1 = $("#qrbcalc_locator1").val();
|
||||
let locator2 = $("#qrbcalc_locator2").val();
|
||||
|
@ -557,6 +585,37 @@ function newpath(latlng1, latlng2, locator1, locator2) {
|
|||
}).addTo(map);
|
||||
}
|
||||
|
||||
function showActivatorsMap(call, count, grids) {
|
||||
|
||||
let re = /,/g;
|
||||
grids = grids.replace(re, ', ');
|
||||
|
||||
var result = "Callsign: "+call.replace('0', 'Ø')+"<br />";
|
||||
result += "Count: "+count+"<br/>";
|
||||
result += "Grids: "+grids+"<br/><br />";
|
||||
|
||||
$(".activatorsmapResult").html(result);
|
||||
|
||||
// If map is already initialized
|
||||
var container = L.DomUtil.get('mapactivators');
|
||||
|
||||
if(container != null){
|
||||
container._leaflet_id = null;
|
||||
}
|
||||
|
||||
const map = new L.map('mapactivators').setView([30, 0], 1.5);
|
||||
|
||||
var grid_four = grids.split(', ');
|
||||
|
||||
var maidenhead = new L.maidenheadactivators(grid_four).addTo(map);
|
||||
|
||||
var osmUrl='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
|
||||
var osmAttrib='Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors';
|
||||
var osm = new L.TileLayer(osmUrl, {minZoom: 1, maxZoom: 9, attribution: osmAttrib});
|
||||
|
||||
map.addLayer(osm);
|
||||
}
|
||||
|
||||
// This displays the dialog with the form and it's where the resulttable is displayed
|
||||
function spawnLookupModal() {
|
||||
$.ajax({
|
||||
|
|
|
@ -349,3 +349,8 @@ div#station_logbooks_linked_table_paginate {
|
|||
max-height: 250px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
#mapactivators {
|
||||
height: calc(100vh - 380px) !important;
|
||||
max-height: 900px !important;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,209 @@
|
|||
/*
|
||||
* L.Maidenhead displays activated grids on the map
|
||||
*/
|
||||
|
||||
L.MaidenheadActivators = L.LayerGroup.extend({
|
||||
|
||||
|
||||
options: {
|
||||
// Line and label color
|
||||
color: 'rgba(255, 0, 0, 0.4)',
|
||||
|
||||
// Redraw on move or moveend
|
||||
redraw: 'move',
|
||||
},
|
||||
|
||||
initialize: function (grids, options) {
|
||||
this.grids = grids;
|
||||
L.LayerGroup.prototype.initialize.call(this);
|
||||
L.Util.setOptions(this, options);
|
||||
|
||||
},
|
||||
|
||||
onAdd: function (map) {
|
||||
this._map = map;
|
||||
var grid = this.redraw(map);
|
||||
this._map.on('viewreset '+ this.options.redraw, function () {
|
||||
grid.redraw(map);
|
||||
});
|
||||
|
||||
this.eachLayer(map.addLayer, map);
|
||||
},
|
||||
|
||||
onRemove: function (map) {
|
||||
// remove layer listeners and elements
|
||||
map.off('viewreset '+ this.options.redraw, this.map);
|
||||
this.eachLayer(this.removeLayer, this);
|
||||
},
|
||||
|
||||
redraw: function (map) {
|
||||
var d3 = new Array(20, 10, 10, 1, 1, 1, 1, 1, 1, 1, 1 / 24, 1 / 24, 1 / 24, 1 / 24, 1 / 24, 1 / 240, 1 / 240, 1 / 240, 1 / 240, 1 / 240 / 24, 1 / 240 / 24);
|
||||
var lat_cor = new Array(0, 8, 8, 8, 8, 1.7, 6, 8, 8, 8, 1.4, 2.5, 3, 3.5, 4, 4, 3.5, 3.5, 3, 1.8, 1.6);
|
||||
var bounds = map.getBounds();
|
||||
var zoom = map.getZoom();
|
||||
var unit = d3[zoom];
|
||||
var lcor = lat_cor[zoom];
|
||||
var w = bounds.getWest();
|
||||
var e = bounds.getEast();
|
||||
var n = bounds.getNorth();
|
||||
var s = bounds.getSouth();
|
||||
if (zoom==1) {var c = 2;} else {var c = 0.1;}
|
||||
if (n > 85) n = 85;
|
||||
if (s < -85) s = -85;
|
||||
var left = Math.floor(w/(unit*2))*(unit*2);
|
||||
var right = Math.ceil(e/(unit*2))*(unit*2);
|
||||
var top = Math.ceil(n/unit)*unit;
|
||||
var bottom = Math.floor(s/unit)*unit;
|
||||
this.eachLayer(this.removeLayer, this);
|
||||
|
||||
var grid_four = this.grids;
|
||||
var grid_two = [];
|
||||
|
||||
function addGridTwo(element, index, array) {
|
||||
if (!grid_two.includes(element.substr(0,2))) {
|
||||
grid_two.push(element.substr(0,2));
|
||||
}
|
||||
}
|
||||
|
||||
grid_four.forEach(addGridTwo);
|
||||
|
||||
for (var lon = left; lon < right; lon += (unit*2)) {
|
||||
for (var lat = bottom; lat < top; lat += unit) {
|
||||
var bounds = [[lat,lon],[lat+unit,lon+(unit*2)]];
|
||||
|
||||
if(grid_two.includes(this._getLocator(lon,lat,map))) {
|
||||
this.addLayer(L.rectangle(bounds, {className: 'grid-rectangle grid-confirmed', color: 'rgba(144,238,144, 0.6)', weight: 1, fillOpacity: 1, fill:true, interactive: false}));
|
||||
}
|
||||
|
||||
if(grid_four.includes(this._getLocator(lon,lat,map))) {
|
||||
this.addLayer(L.rectangle(bounds, {className: 'grid-rectangle grid-confirmed', color: 'rgba(144,238,144, 0.6)', weight: 1, fillOpacity: 1, fill:true, interactive: false}));
|
||||
}
|
||||
|
||||
if (zoom < 2 || zoom > 4) {
|
||||
this.addLayer(this._getLabel(lon+unit-(unit/lcor),lat+(unit/2)+(unit/lcor*c), map));
|
||||
}
|
||||
if (zoom < 3 ) {
|
||||
this.addLayer(L.rectangle(bounds, {className: 'grid-rectangle', color: this.options.color, weight: 1, fill:false, interactive: false}));
|
||||
}
|
||||
if (zoom < 3 || zoom > 5) {
|
||||
this.addLayer(L.rectangle(bounds, {className: 'grid-rectangle', color: this.options.color, weight: 1, fill:false, interactive: false}));
|
||||
}
|
||||
|
||||
if (zoom < 3 || zoom > 5) {
|
||||
this.addLayer(this._getLabel(lon+unit-(unit/lcor),lat+(unit/2)+(unit/lcor*c), map));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// Added this to print fields and field name, while still showing worked/confirmed gridsquares
|
||||
if (zoom < 5 && zoom > 2) {
|
||||
unit = 10;
|
||||
var left = Math.floor(w / (unit * 2)) * (unit * 2);
|
||||
var right = Math.ceil(e / (unit * 2)) * (unit * 2);
|
||||
var top = Math.ceil(n / unit) * unit;
|
||||
var bottom = Math.floor(s / unit) * unit;
|
||||
for (var lon = left; lon < right; lon += (unit * 2)) {
|
||||
for (var lat = bottom; lat < top; lat += unit) {
|
||||
var bounds = [[lat, lon], [lat + unit, lon + (unit * 2)]];
|
||||
|
||||
this.addLayer(L.rectangle(bounds, {
|
||||
className: 'grid-rectangle',
|
||||
color: this.options.color,
|
||||
weight: 1,
|
||||
fill: false,
|
||||
interactive: false
|
||||
}));
|
||||
this.addLayer(this._getLabel2(lon + unit - (unit / lcor), lat + (unit / 2) + (unit / lcor * c), map));
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
_getLabel: function(lon,lat, map) {
|
||||
var title_size = new Array(0, 10, 14, 16, 6, 13, 14, 16, 24, 36, 12, 14, 20, 36, 60, 12, 20, 36, 60, 12, 24);
|
||||
var zoom = map.getZoom();
|
||||
var size = title_size[zoom]+'px';
|
||||
var title = '<span class="grid-text" style="cursor: default;"><font style="color:'+this.options.color+'; font-size:'+size+'; font-weight: 900; ">' + this._getLocator(lon,lat, map) + '</font></span>';
|
||||
var myIcon = L.divIcon({className: 'my-div-icon', html: title});
|
||||
var marker = L.marker([lat,lon], {icon: myIcon}, clickable=false);
|
||||
return marker;
|
||||
},
|
||||
|
||||
_getLocator: function(lon,lat, map) {
|
||||
var ydiv_arr=new Array(10, 1, 1/24, 1/240, 1/240/24);
|
||||
var d1 = "ABCDEFGHIJKLMNOPQR".split("");
|
||||
var d2 = "ABCDEFGHIJKLMNOPQRSTUVWX".split("");
|
||||
var d4 = new Array(0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5);
|
||||
var locator = "";
|
||||
var x = lon;
|
||||
var y = lat;
|
||||
var precision = d4[map.getZoom()];
|
||||
while (x < -180) {x += 360;}
|
||||
while (x > 180) {x -=360;}
|
||||
x = x + 180;
|
||||
y = y + 90;
|
||||
locator = locator + d1[Math.floor(x/20)] + d1[Math.floor(y/10)];
|
||||
for (var i=0; i<4; i=i+1) {
|
||||
if (precision > i+1) {
|
||||
rlon = x%(ydiv_arr[i]*2);
|
||||
rlat = y%(ydiv_arr[i]);
|
||||
if ((i%2)==0) {
|
||||
locator += Math.floor(rlon/(ydiv_arr[i+1]*2)) +""+ Math.floor(rlat/(ydiv_arr[i+1]));
|
||||
} else {
|
||||
locator += d2[Math.floor(rlon/(ydiv_arr[i+1]*2))] +""+ d2[Math.floor(rlat/(ydiv_arr[i+1]))];
|
||||
}
|
||||
}
|
||||
}
|
||||
return locator;
|
||||
},
|
||||
|
||||
/*
|
||||
Need this for the field printing, while showing worked/confirmed grids
|
||||
*/
|
||||
_getLabel2: function(lon,lat, map) {
|
||||
var title_size = new Array(0, 10, 12, 16, 20, 26, 26, 16, 24, 36, 12, 14, 20, 36, 60, 12, 20, 36, 60, 12, 24);
|
||||
var zoom = map.getZoom();
|
||||
var size = title_size[zoom]+'px';
|
||||
var title = '<span class="grid-text" style="cursor: default;"><font style="color:'+this.options.color+'; font-size:'+size+'; font-weight: 900; ">' + this._getLocator2(lon,lat, map) + '</font></span>';
|
||||
var myIcon = L.divIcon({className: 'my-div-icon', html: title});
|
||||
var marker = L.marker([lat,lon], {icon: myIcon}, clickable=false);
|
||||
return marker;
|
||||
},
|
||||
|
||||
/*
|
||||
Need this for the field printing, while showing worked/confirmed grids
|
||||
*/
|
||||
_getLocator2: function(lon,lat, map) {
|
||||
var ydiv_arr=new Array(10, 1, 1/24, 1/240, 1/240/24);
|
||||
var d1 = "ABCDEFGHIJKLMNOPQR".split("");
|
||||
var d2 = "ABCDEFGHIJKLMNOPQRSTUVWX".split("");
|
||||
var d4 = new Array(0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5);
|
||||
var locator = "";
|
||||
var x = lon;
|
||||
var y = lat;
|
||||
var precision = d4[map.getZoom()];
|
||||
while (x < -180) {x += 360;}
|
||||
while (x > 180) {x -=360;}
|
||||
x = x + 180;
|
||||
y = y + 90;
|
||||
locator = locator + d1[Math.floor(x/20)] + d1[Math.floor(y/10)];
|
||||
for (var i=0; i<4; i=i+1) {
|
||||
if (precision > i+1) {
|
||||
rlon = x%(ydiv_arr[i]*2);
|
||||
rlat = y%(ydiv_arr[i]);
|
||||
if ((i%2)==0) {
|
||||
locator += Math.floor(rlon/(ydiv_arr[i+1]*2)) +""+ Math.floor(rlat/(ydiv_arr[i+1]));
|
||||
} else {
|
||||
locator += d2[Math.floor(rlon/(ydiv_arr[i+1]*2))] +""+ d2[Math.floor(rlat/(ydiv_arr[i+1]))];
|
||||
}
|
||||
}
|
||||
}
|
||||
return locator;
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
L.maidenheadactivators = function (options) {
|
||||
return new L.MaidenheadActivators(options);
|
||||
};
|
Ładowanie…
Reference in New Issue