[Gridsquare Map] Added display of coordinates, gridsquare, distance and bearing when mouseover
这个提交包含在:
父节点
a6da3c1277
当前提交
36fdce5eca
共有 4 个文件被更改,包括 148 次插入 和 2 次删除
|
|
@ -11,6 +11,9 @@ class Gridmap extends CI_Controller {
|
|||
|
||||
$this->load->model('bands');
|
||||
$this->load->model('gridmap_model');
|
||||
$this->load->model('stations');
|
||||
|
||||
$data['homegrid'] = explode(',', $this->stations->find_gridsquare());
|
||||
|
||||
$data['modes'] = $this->gridmap_model->get_worked_modes();
|
||||
$data['bands'] = $this->bands->get_worked_bands();
|
||||
|
|
@ -27,6 +30,7 @@ class Gridmap extends CI_Controller {
|
|||
|
||||
$footerData = [];
|
||||
$footerData['scripts'] = [
|
||||
'assets/js/leaflet/geocoding.js',
|
||||
'assets/js/leaflet/L.MaidenheadColouredGridMap.js',
|
||||
'assets/js/sections/gridmap.js?'
|
||||
];
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@
|
|||
padding: 6px 8px;
|
||||
font: 14px Arial, Helvetica, sans-serif;
|
||||
background: white;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
line-height: 24px;
|
||||
color: #555;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.legend h4 {
|
||||
text-align: center;
|
||||
|
|
@ -25,7 +25,13 @@
|
|||
height: 18px;
|
||||
float: left;
|
||||
margin: 0 8px 0 0;
|
||||
opacity: 0.7;
|
||||
}
|
||||
.coordinates {
|
||||
justify-content: center;
|
||||
align-items: stretch;
|
||||
}
|
||||
.cohidden {
|
||||
display:none;
|
||||
}
|
||||
</style>
|
||||
<div class="container">
|
||||
|
|
@ -94,10 +100,23 @@
|
|||
<div id="gridmapcontainer">
|
||||
<div id="gridsquare_map" style="width: 100%; height: 800px"></div>
|
||||
</div>
|
||||
<div class="coordinates text-center d-flex">
|
||||
<div class="cohidden">Latitude: </div>
|
||||
<div class="cohidden col-auto text-success font-weight-bold" id="latDeg"></div>
|
||||
<div class="cohidden">Longitude: </div>
|
||||
<div class="cohidden col-auto text-success font-weight-bold" id="lngDeg"></div>
|
||||
<div class="cohidden">Gridsquare: </div>
|
||||
<div class="cohidden col-auto text-success font-weight-bold" id="locator"></div>
|
||||
<div class="cohidden">Distance: </div>
|
||||
<div class="cohidden col-auto text-success font-weight-bold" id="distance"></div>
|
||||
<div class="cohidden">Bearing: </div>
|
||||
<div class="cohidden col-auto text-success font-weight-bold" id="bearing"></div>
|
||||
</div>
|
||||
<script>var gridsquaremap = true;
|
||||
<?php
|
||||
echo 'var jslayer ="' . $layer .'";';
|
||||
echo "var jsattribution ='" . $attribution . "';";
|
||||
echo "var homegrid ='" . strtoupper($homegrid[0]) . "';";
|
||||
|
||||
echo 'var gridsquares_gridsquares = "' . $gridsquares_gridsquares . '";';
|
||||
echo 'var gridsquares_gridsquares_confirmed = "' . $gridsquares_gridsquares_confirmed . '";';
|
||||
|
|
|
|||
121
assets/js/leaflet/geocoding.js
普通文件
121
assets/js/leaflet/geocoding.js
普通文件
|
|
@ -0,0 +1,121 @@
|
|||
const isValidLocatorString = locatorString => locatorString.match(/^[A-Ra-r][A-Ra-r]\d\d[A-Xa-x][A-Xa-x]/) !== null;
|
||||
const charToNumber = char => char.toUpperCase().charCodeAt(0) - CHAR_CODE_OFFSET;
|
||||
const numberToChar = number => String.fromCharCode(number + CHAR_CODE_OFFSET);
|
||||
const CHAR_CODE_OFFSET = 65;
|
||||
const degToRad = deg => (deg % 360) * Math.PI / 180;
|
||||
const radToDeg = rad => (rad / Math.PI *180) % 360;
|
||||
const isValidPoint = (lat, lng) => (lat >= -90 && lat <= 90) && (lng >= -180 && lng <= 180);
|
||||
|
||||
function ConvertDDToDMS(lat, lng) {
|
||||
var LatLng = [];
|
||||
|
||||
if (lng < -180) {
|
||||
lng = lng + 360;
|
||||
}
|
||||
if (lng > 180) {
|
||||
lng = lng - 360;
|
||||
}
|
||||
|
||||
LatLng['latDeg'] = (lat < 0 ? "S" : "N") + " " + (0 | (lat < 0 ? (lat = -lat) : lat)) + "° " + (0 | (((lat += 1e-9) % 1) * 60)) + "' " + ((0 | (((lat * 60) % 1) * 6000)) / 100) + "\"";
|
||||
|
||||
LatLng['lngDeg'] = (lng < 0 ? "W" : "E") + " " + (0 | (lng < 0 ? (lng = -lng) : lng)) + "° " + (0 | (((lng += 1e-9) % 1) * 60)) + "' " + ((0 | (((lng * 60) % 1) * 6000)) / 100) + "\"";
|
||||
|
||||
return LatLng;
|
||||
}
|
||||
|
||||
const latLngToLocator = (lat, lng) => {
|
||||
if (lng < -180) {
|
||||
lng = lng + 360;
|
||||
}
|
||||
if (lng > 180) {
|
||||
lng = lng - 360;
|
||||
}
|
||||
if (!isValidPoint(lat, lng)) {
|
||||
throw new Error('Input is not a valid coordinate');
|
||||
}
|
||||
|
||||
const longitude = lng + 180;
|
||||
const latitude = lat + 90;
|
||||
|
||||
const fieldLng = numberToChar(Math.floor(longitude / 20));
|
||||
const fieldLat = numberToChar(Math.floor(latitude / 10));
|
||||
|
||||
const squareLng = Math.floor(longitude % 20 / 2);
|
||||
const squareLat = Math.floor(latitude % 10);
|
||||
|
||||
const subsquareLng = numberToChar(Math.floor((longitude % 20 % 2) * 12)).toLowerCase();
|
||||
const subsquareLat = numberToChar((latitude % 10 - squareLat) * 24).toLowerCase();
|
||||
|
||||
return fieldLng + fieldLat + squareLng + squareLat + subsquareLng + subsquareLat;
|
||||
};
|
||||
|
||||
function onMapMove(event) {
|
||||
var LatLng = event.latlng;
|
||||
var lat = LatLng.lat;
|
||||
var lng = LatLng.lng;
|
||||
var LatLng2 = ConvertDDToDMS(lat, lng);
|
||||
$('#latDeg').html(LatLng2.latDeg);
|
||||
$('#lngDeg').html(LatLng2.lngDeg);
|
||||
var locator = latLngToLocator(lat,lng);
|
||||
$('#locator').html(locator);
|
||||
var distance = bearingDistance(homegrid, locator);
|
||||
|
||||
$('#bearing').html(distance.deg + ' deg');
|
||||
$('#distance').html(Math.round(distance.km * 10) / 10 + ' km');
|
||||
};
|
||||
|
||||
const bearingDistance = (from, to) => {
|
||||
const fromCoords = locatorToLatLng(from);
|
||||
const toCoords = locatorToLatLng(to);
|
||||
const dLat = degToRad(toCoords[0] - fromCoords[0]);
|
||||
const dLon = degToRad(toCoords[1] - fromCoords[1]);
|
||||
const fromLat = degToRad(fromCoords[0]);
|
||||
const toLat = degToRad(toCoords[0]);
|
||||
const a = Math.pow(Math.sin(dLat / 2), 2) + Math.pow(Math.sin(dLon / 2), 2) * Math.cos(fromLat) * Math.cos(toLat);
|
||||
const b = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
||||
|
||||
const y = (dLon) * Math.cos(fromLat) * Math.cos(toLat);
|
||||
const x = Math.sin(toLat) - Math.sin(fromLat) * Math.cos(b);
|
||||
|
||||
let az = Math.atan2(y, x);
|
||||
|
||||
if (az < 0) {
|
||||
az += 2 * Math.PI;
|
||||
}
|
||||
|
||||
return {
|
||||
km: b * 6371,
|
||||
deg: calcAngle(fromCoords, toCoords)
|
||||
};
|
||||
};
|
||||
|
||||
var calcAngle = function (p1, p2) {
|
||||
var lat1 = p1[0] / 180 * Math.PI;
|
||||
var lat2 = p2[0] / 180 * Math.PI;
|
||||
var lng1 = p1[1] / 180 * Math.PI;
|
||||
var lng2 = p2[1] / 180 * Math.PI;
|
||||
var y = Math.sin(lng2-lng1) * Math.cos(lat2);
|
||||
var x = Math.cos(lat1)*Math.sin(lat2) - Math.sin(lat1)*Math.cos(lat2)*Math.cos(lng2-lng1);
|
||||
var brng = (Math.atan2(y, x) * 180 / Math.PI + 360).toFixed(0);
|
||||
|
||||
return (brng % 360);
|
||||
}
|
||||
|
||||
const locatorToLatLng = (locatorString) => {
|
||||
locatorString += 'll'; // append subsquare in case is 4 chars long... If not, is ignored.
|
||||
if (!isValidLocatorString(locatorString)) {
|
||||
throw new Error('Input is not valid locator string');
|
||||
}
|
||||
|
||||
const fieldLng = charToNumber(locatorString[0]) * 20;
|
||||
const fieldLat = charToNumber(locatorString[1]) * 10;
|
||||
const squareLng = Number.parseInt(locatorString[2]) * 2;
|
||||
const squareLat = Number.parseInt(locatorString[3]);
|
||||
const subsquareLng = (charToNumber(locatorString[4]) + 0.5) / 12;
|
||||
const subsquareLat = (charToNumber(locatorString[5]) + 0.5) / 24;
|
||||
|
||||
return [
|
||||
fieldLat + squareLat + subsquareLat - 90,
|
||||
fieldLng + squareLng + subsquareLng - 180
|
||||
];
|
||||
};
|
||||
|
|
@ -40,6 +40,7 @@ function gridPlot(form) {
|
|||
sat: $("#sats").val(),
|
||||
},
|
||||
success: function (data) {
|
||||
$('.cohidden').show();
|
||||
$(".ld-ext-right").removeClass('running');
|
||||
$(".ld-ext-right").prop('disabled', false);
|
||||
$('#plot').prop("disabled", false);
|
||||
|
|
@ -89,6 +90,7 @@ function gridPlot(form) {
|
|||
legend.addTo(map);
|
||||
|
||||
var maidenhead = L.maidenhead().addTo(map);
|
||||
map.on('mousemove', onMapMove);
|
||||
},
|
||||
error: function (data) {
|
||||
},
|
||||
|
|
|
|||
正在加载…
在新工单中引用