From ea6e7f20f6db64edb6b41a73cc3753a6cff5f904 Mon Sep 17 00:00:00 2001 From: phl0 Date: Sun, 12 Jun 2022 13:18:26 +0200 Subject: [PATCH] Add activators map --- application/controllers/Activatorsmap.php | 30 +++ application/views/activators/index.php | 4 +- application/views/activatorsmap/index.php | 2 + application/views/interface_assets/footer.php | 67 ++++++ assets/js/leaflet/L.Maidenhead.activators.js | 197 ++++++++++++++++++ 5 files changed, 298 insertions(+), 2 deletions(-) create mode 100644 application/controllers/Activatorsmap.php create mode 100644 application/views/activatorsmap/index.php create mode 100644 assets/js/leaflet/L.Maidenhead.activators.js diff --git a/application/controllers/Activatorsmap.php b/application/controllers/Activatorsmap.php new file mode 100644 index 00000000..4d0dcfdb --- /dev/null +++ b/application/controllers/Activatorsmap.php @@ -0,0 +1,30 @@ +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); + } +} diff --git a/application/views/activators/index.php b/application/views/activators/index.php index 79832e89..013ebaed 100644 --- a/application/views/activators/index.php +++ b/application/views/activators/index.php @@ -133,8 +133,8 @@ function write_activators($activators_array, $vucc_grids, $custom_date_format, $ '.$line[1].' '.$line[0].' '.$line[2].' - Show - Show + + '; } echo ''; diff --git a/application/views/activatorsmap/index.php b/application/views/activatorsmap/index.php new file mode 100644 index 00000000..51e28cf2 --- /dev/null +++ b/application/views/activatorsmap/index.php @@ -0,0 +1,2 @@ +
+
diff --git a/application/views/interface_assets/footer.php b/application/views/interface_assets/footer.php index 64b2472b..ae4b1cdb 100644 --- a/application/views/interface_assets/footer.php +++ b/application/views/interface_assets/footer.php @@ -6,6 +6,9 @@ +uri->segment(1) == "activators") { ?> + + @@ -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,45 @@ function newpath(latlng1, latlng2, locator1, locator2) { }).addTo(map); } +function showActivatorsMap(call, count, grids) { + + let re = /,/g; + grids = grids.replace(re, ', '); + $.ajax({ + url: base_url+'index.php/qrbcalc/calculate', + type: 'post', + data: {'grids': "test"}, + success: function (html) { + + var result = "Callsign: "+call+"
"; + result += "Count: "+count+"
"; + result += "Grids: "+grids+"

"; + + $(".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 © OpenStreetMap 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({ diff --git a/assets/js/leaflet/L.Maidenhead.activators.js b/assets/js/leaflet/L.Maidenhead.activators.js new file mode 100644 index 00000000..4b6e585e --- /dev/null +++ b/assets/js/leaflet/L.Maidenhead.activators.js @@ -0,0 +1,197 @@ +/* + * 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; + + 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_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})); + } + console.log('Zoom: '+zoom); + + 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 = '' + this._getLocator(lon,lat, map) + ''; + 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 = '' + this._getLocator2(lon,lat, map) + ''; + 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); +};