a968f03c3a
In the table view of aircraft, the heading was displayed as "330 (NW)" or similar. However, this cause the entry to scroll over into two lines of text, and reduces the number of planes that can be seen in the table at any one time. There probably should be a way to make the table view wider by scrolling it, but I can't see any way to do that. So for the moment I've commented out the extra (NW) bit.
627 lines
18 KiB
JavaScript
627 lines
18 KiB
JavaScript
// Define our global variables
|
|
var GoogleMap = null;
|
|
var Planes = {};
|
|
var PlanesOnMap = 0;
|
|
var PlanesOnTable = 0;
|
|
var PlanesToReap = 0;
|
|
var SelectedPlane = null;
|
|
var SpecialSquawk = false;
|
|
|
|
var iSortCol=-1;
|
|
var bSortASC=true;
|
|
var bDefaultSortASC=true;
|
|
var iDefaultSortCol=3;
|
|
|
|
// Get current map settings
|
|
CenterLat = Number(localStorage['CenterLat']) || CONST_CENTERLAT;
|
|
CenterLon = Number(localStorage['CenterLon']) || CONST_CENTERLON;
|
|
ZoomLvl = Number(localStorage['ZoomLvl']) || CONST_ZOOMLVL;
|
|
|
|
function fetchData() {
|
|
$.getJSON('/dump1090/data.json', function(data) {
|
|
PlanesOnMap = 0
|
|
SpecialSquawk = false;
|
|
|
|
// Loop through all the planes in the data packet
|
|
for (var j=0; j < data.length; j++) {
|
|
// Do we already have this plane object in Planes?
|
|
// If not make it.
|
|
if (Planes[data[j].hex]) {
|
|
var plane = Planes[data[j].hex];
|
|
} else {
|
|
var plane = jQuery.extend(true, {}, planeObject);
|
|
}
|
|
|
|
/* For special squawk tests
|
|
if (data[j].hex == '48413x') {
|
|
data[j].squawk = '7700';
|
|
} //*/
|
|
|
|
// Set SpecialSquawk-value
|
|
if (data[j].squawk == '7500' || data[j].squawk == '7600' || data[j].squawk == '7700') {
|
|
SpecialSquawk = true;
|
|
}
|
|
|
|
// Call the function update
|
|
plane.funcUpdateData(data[j]);
|
|
|
|
// Copy the plane into Planes
|
|
Planes[plane.icao] = plane;
|
|
}
|
|
|
|
PlanesOnTable = data.length;
|
|
});
|
|
}
|
|
|
|
// Initalizes the map and starts up our timers to call various functions
|
|
function initialize() {
|
|
// Make a list of all the available map IDs
|
|
var mapTypeIds = [];
|
|
for(var type in google.maps.MapTypeId) {
|
|
mapTypeIds.push(google.maps.MapTypeId[type]);
|
|
}
|
|
// Push OSM on to the end
|
|
mapTypeIds.push("OSM");
|
|
mapTypeIds.push("dark_map");
|
|
|
|
// Styled Map to outline airports and highways
|
|
var styles = [
|
|
{
|
|
"featureType": "administrative",
|
|
"stylers": [
|
|
{ "visibility": "off" }
|
|
]
|
|
},{
|
|
"featureType": "landscape",
|
|
"stylers": [
|
|
{ "visibility": "off" }
|
|
]
|
|
},{
|
|
"featureType": "poi",
|
|
"stylers": [
|
|
{ "visibility": "off" }
|
|
]
|
|
},{
|
|
"featureType": "road",
|
|
"stylers": [
|
|
{ "visibility": "off" }
|
|
]
|
|
},{
|
|
"featureType": "transit",
|
|
"stylers": [
|
|
{ "visibility": "off" }
|
|
]
|
|
},{
|
|
"featureType": "landscape",
|
|
"stylers": [
|
|
{ "visibility": "on" },
|
|
{ "weight": 8 },
|
|
{ "color": "#000000" }
|
|
]
|
|
},{
|
|
"featureType": "water",
|
|
"stylers": [
|
|
{ "lightness": -74 }
|
|
]
|
|
},{
|
|
"featureType": "transit.station.airport",
|
|
"stylers": [
|
|
{ "visibility": "on" },
|
|
{ "weight": 8 },
|
|
{ "invert_lightness": true },
|
|
{ "lightness": 27 }
|
|
]
|
|
},{
|
|
"featureType": "road.highway",
|
|
"stylers": [
|
|
{ "visibility": "simplified" },
|
|
{ "invert_lightness": true },
|
|
{ "gamma": 0.3 }
|
|
]
|
|
},{
|
|
"featureType": "road",
|
|
"elementType": "labels",
|
|
"stylers": [
|
|
{ "visibility": "off" }
|
|
]
|
|
}
|
|
]
|
|
|
|
// Add our styled map
|
|
var styledMap = new google.maps.StyledMapType(styles, {name: "Dark Map"});
|
|
|
|
// Define the Google Map
|
|
var mapOptions = {
|
|
center: new google.maps.LatLng(CenterLat, CenterLon),
|
|
zoom: ZoomLvl,
|
|
mapTypeId: google.maps.MapTypeId.ROADMAP,
|
|
mapTypeControlOptions: {
|
|
mapTypeIds: mapTypeIds
|
|
}
|
|
};
|
|
|
|
GoogleMap = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
|
|
|
|
//Define OSM map type pointing at the OpenStreetMap tile server
|
|
GoogleMap.mapTypes.set("OSM", new google.maps.ImageMapType({
|
|
getTileUrl: function(coord, zoom) {
|
|
return "http://tile.openstreetmap.org/" + zoom + "/" + coord.x + "/" + coord.y + ".png";
|
|
},
|
|
tileSize: new google.maps.Size(256, 256),
|
|
name: "OpenStreetMap",
|
|
maxZoom: 18
|
|
}));
|
|
|
|
GoogleMap.mapTypes.set("dark_map", styledMap);
|
|
|
|
// Listeners for newly created Map
|
|
google.maps.event.addListener(GoogleMap, 'center_changed', function() {
|
|
localStorage['CenterLat'] = GoogleMap.getCenter().lat();
|
|
localStorage['CenterLon'] = GoogleMap.getCenter().lng();
|
|
});
|
|
|
|
google.maps.event.addListener(GoogleMap, 'zoom_changed', function() {
|
|
localStorage['ZoomLvl'] = GoogleMap.getZoom();
|
|
});
|
|
|
|
// Add home marker if requested
|
|
if (SiteShow && (typeof SiteLat !== 'undefined' || typeof SiteLon !== 'undefined')) {
|
|
var siteMarker = new google.maps.LatLng(SiteLat, SiteLon);
|
|
var markerImage = new google.maps.MarkerImage(
|
|
'http://maps.google.com/mapfiles/kml/pal4/icon57.png',
|
|
new google.maps.Size(32, 32), // Image size
|
|
new google.maps.Point(0, 0), // Origin point of image
|
|
new google.maps.Point(16, 16)); // Position where marker should point
|
|
var marker = new google.maps.Marker({
|
|
position: siteMarker,
|
|
map: GoogleMap,
|
|
icon: markerImage,
|
|
title: 'My Radar Site',
|
|
zIndex: -99999
|
|
});
|
|
|
|
if (SiteCircles) {
|
|
for (var i=0;i<SiteCirclesDistances.length;i++) {
|
|
drawCircle(marker, SiteCirclesDistances[i]); // in meters
|
|
}
|
|
}
|
|
}
|
|
|
|
// These will run after page is complitely loaded
|
|
$(window).load(function() {
|
|
$('#dialog-modal').css('display', 'inline'); // Show hidden settings-windows content
|
|
});
|
|
|
|
// Load up our options page
|
|
optionsInitalize();
|
|
|
|
// Did our crafty user need some setup?
|
|
extendedInitalize();
|
|
|
|
// Setup our timer to poll from the server.
|
|
window.setInterval(function() {
|
|
fetchData();
|
|
refreshTableInfo();
|
|
refreshSelected();
|
|
reaper();
|
|
extendedPulse();
|
|
}, 1000);
|
|
}
|
|
|
|
// This looks for planes to reap out of the master Planes variable
|
|
function reaper() {
|
|
PlanesToReap = 0;
|
|
// When did the reaper start?
|
|
reaptime = new Date().getTime();
|
|
// Loop the planes
|
|
for (var reap in Planes) {
|
|
// Is this plane possibly reapable?
|
|
if (Planes[reap].reapable == true) {
|
|
// Has it not been seen for 5 minutes?
|
|
// This way we still have it if it returns before then
|
|
// Due to loss of signal or other reasons
|
|
if ((reaptime - Planes[reap].updated) > 300000) {
|
|
// Reap it.
|
|
delete Planes[reap];
|
|
}
|
|
PlanesToReap++;
|
|
}
|
|
};
|
|
}
|
|
|
|
// Refresh the detail window about the plane
|
|
function refreshSelected() {
|
|
var selected = false;
|
|
if (typeof SelectedPlane !== 'undefined' && SelectedPlane != "ICAO" && SelectedPlane != null) {
|
|
selected = Planes[SelectedPlane];
|
|
}
|
|
|
|
var columns = 2;
|
|
var html = '';
|
|
|
|
if (selected) {
|
|
html += '<table id="selectedinfo" width="100%">';
|
|
} else {
|
|
html += '<table id="selectedinfo" class="dim" width="100%">';
|
|
}
|
|
|
|
// Flight header line including squawk if needed
|
|
if (selected && selected.flight == "") {
|
|
html += '<tr><td colspan="' + columns + '" id="selectedinfotitle"><b>N/A (' +
|
|
selected.icao + ')</b>';
|
|
} else if (selected && selected.flight != "") {
|
|
html += '<tr><td colspan="' + columns + '" id="selectedinfotitle"><b>' +
|
|
selected.flight + '</b>';
|
|
} else {
|
|
html += '<tr><td colspan="' + columns + '" id="selectedinfotitle"><b>DUMP1090</b>';
|
|
}
|
|
|
|
if (selected && selected.squawk == 7500) { // Lets hope we never see this... Aircraft Hijacking
|
|
html += ' <span class="squawk7500"> Squawking: Aircraft Hijacking </span>';
|
|
} else if (selected && selected.squawk == 7600) { // Radio Failure
|
|
html += ' <span class="squawk7600"> Squawking: Radio Failure </span>';
|
|
} else if (selected && selected.squawk == 7700) { // General Emergency
|
|
html += ' <span class="squawk7700"> Squawking: General Emergency </span>';
|
|
} else if (selected && selected.flight != '') {
|
|
html += ' <a href="http://www.flightstats.com/go/FlightStatus/flightStatusByFlight.do?';
|
|
html += 'flightNumber='+selected.flight+'" target="_blank">[FlightStats]</a>';
|
|
}
|
|
html += '<td></tr>';
|
|
|
|
if (selected) {
|
|
if (Metric) {
|
|
html += '<tr><td>Altitude: ' + Math.round(selected.altitude / 3.2828) + ' m</td>';
|
|
} else {
|
|
html += '<tr><td>Altitude: ' + selected.altitude + ' ft</td>';
|
|
}
|
|
} else {
|
|
html += '<tr><td>Altitude: n/a</td>';
|
|
}
|
|
|
|
if (selected && selected.squawk != '0000') {
|
|
html += '<td>Squawk: ' + selected.squawk + '</td></tr>';
|
|
} else {
|
|
html += '<td>Squawk: n/a</td></tr>';
|
|
}
|
|
|
|
html += '<tr><td>Speed: '
|
|
if (selected) {
|
|
if (Metric) {
|
|
html += Math.round(selected.speed * 1.852) + ' km/h';
|
|
} else {
|
|
html += selected.speed + ' kt';
|
|
}
|
|
} else {
|
|
html += 'n/a';
|
|
}
|
|
html += '</td>';
|
|
|
|
if (selected) {
|
|
html += '<td>ICAO (hex): ' + selected.icao + '</td></tr>';
|
|
} else {
|
|
html += '<td>ICAO (hex): n/a</td></tr>'; // Something is wrong if we are here
|
|
}
|
|
|
|
html += '<tr><td>Track: '
|
|
if (selected && selected.vTrack) {
|
|
html += selected.track + ' (' + normalizeTrack(selected.track, selected.vTrack)[1] +')';
|
|
} else {
|
|
html += 'n/a';
|
|
}
|
|
html += '</td><td> </td></tr>';
|
|
|
|
html += '<tr><td colspan="' + columns + '" align="center">Lat/Long: ';
|
|
if (selected && selected.vPosition) {
|
|
html += selected.latitude + ', ' + selected.longitude + '</td></tr>';
|
|
|
|
// Let's show some extra data if we have site coordinates
|
|
if (SiteShow) {
|
|
var siteLatLon = new google.maps.LatLng(SiteLat, SiteLon);
|
|
var planeLatLon = new google.maps.LatLng(selected.latitude, selected.longitude);
|
|
var dist = google.maps.geometry.spherical.computeDistanceBetween (siteLatLon, planeLatLon);
|
|
|
|
if (Metric) {
|
|
dist /= 1000;
|
|
} else {
|
|
dist /= 1852;
|
|
}
|
|
dist = (Math.round((dist)*10)/10).toFixed(1);
|
|
html += '<tr><td colspan="' + columns + '">Distance from Site: ' + dist +
|
|
(Metric ? ' km' : ' NM') + '</td></tr>';
|
|
} // End of SiteShow
|
|
} else {
|
|
if (SiteShow) {
|
|
html += '<tr><td colspan="' + columns + '">Distance from Site: n/a ' +
|
|
(Metric ? ' km' : ' NM') + '</td></tr>';
|
|
} else {
|
|
html += 'n/a</td></tr>';
|
|
}
|
|
}
|
|
|
|
html += '</table>';
|
|
|
|
document.getElementById('plane_detail').innerHTML = html;
|
|
}
|
|
|
|
// Right now we have no means to validate the speed is good
|
|
// Want to return (n/a) when we dont have it
|
|
// TODO: Edit C code to add a valid speed flag
|
|
// TODO: Edit js code to use said flag
|
|
function normalizeSpeed(speed, valid) {
|
|
return speed
|
|
}
|
|
|
|
// Returns back a long string, short string, and the track if we have a vaild track path
|
|
function normalizeTrack(track, valid){
|
|
x = []
|
|
if ((track > -1) && (track < 22.5)) {
|
|
x = ["North", "N", track]
|
|
}
|
|
if ((track > 22.5) && (track < 67.5)) {
|
|
x = ["North East", "NE", track]
|
|
}
|
|
if ((track > 67.5) && (track < 112.5)) {
|
|
x = ["East", "E", track]
|
|
}
|
|
if ((track > 112.5) && (track < 157.5)) {
|
|
x = ["South East", "SE", track]
|
|
}
|
|
if ((track > 157.5) && (track < 202.5)) {
|
|
x = ["South", "S", track]
|
|
}
|
|
if ((track > 202.5) && (track < 247.5)) {
|
|
x = ["South West", "SW", track]
|
|
}
|
|
if ((track > 247.5) && (track < 292.5)) {
|
|
x = ["West", "W", track]
|
|
}
|
|
if ((track > 292.5) && (track < 337.5)) {
|
|
x = ["North West", "NW", track]
|
|
}
|
|
if ((track > 337.5) && (track < 361)) {
|
|
x = ["North", "N", track]
|
|
}
|
|
if (!valid) {
|
|
x = [" ", "n/a", ""]
|
|
}
|
|
return x
|
|
}
|
|
|
|
// Refeshes the larger table of all the planes
|
|
function refreshTableInfo() {
|
|
var html = '<table id="tableinfo" width="100%">';
|
|
html += '<thead style="background-color: #BBBBBB; cursor: pointer;">';
|
|
html += '<td onclick="setASC_DESC(\'0\');sortTable(\'tableinfo\',\'0\');">ICAO</td>';
|
|
html += '<td onclick="setASC_DESC(\'1\');sortTable(\'tableinfo\',\'1\');">Flight</td>';
|
|
html += '<td onclick="setASC_DESC(\'2\');sortTable(\'tableinfo\',\'2\');" ' +
|
|
'align="right">Squawk</td>';
|
|
html += '<td onclick="setASC_DESC(\'3\');sortTable(\'tableinfo\',\'3\');" ' +
|
|
'align="right">Altitude</td>';
|
|
html += '<td onclick="setASC_DESC(\'4\');sortTable(\'tableinfo\',\'4\');" ' +
|
|
'align="right">Speed</td>';
|
|
html += '<td onclick="setASC_DESC(\'5\');sortTable(\'tableinfo\',\'5\');" ' +
|
|
'align="right">Track</td>';
|
|
html += '<td onclick="setASC_DESC(\'6\');sortTable(\'tableinfo\',\'6\');" ' +
|
|
'align="right">Msgs</td>';
|
|
html += '<td onclick="setASC_DESC(\'7\');sortTable(\'tableinfo\',\'7\');" ' +
|
|
'align="right">Seen</td></thead><tbody>';
|
|
for (var tablep in Planes) {
|
|
var tableplane = Planes[tablep]
|
|
if (!tableplane.reapable) {
|
|
var specialStyle = "";
|
|
// Is this the plane we selected?
|
|
if (tableplane.icao == SelectedPlane) {
|
|
specialStyle += " selected";
|
|
}
|
|
// Lets hope we never see this... Aircraft Hijacking
|
|
if (tableplane.squawk == 7500) {
|
|
specialStyle += " squawk7500";
|
|
}
|
|
// Radio Failure
|
|
if (tableplane.squawk == 7600) {
|
|
specialStyle += " squawk7600";
|
|
}
|
|
// Emergancy
|
|
if (tableplane.squawk == 7700) {
|
|
specialStyle += " squawk7700";
|
|
}
|
|
|
|
if (tableplane.vPosition == true) {
|
|
html += '<tr class="plane_table_row vPosition' + specialStyle + '">';
|
|
} else {
|
|
html += '<tr class="plane_table_row ' + specialStyle + '">';
|
|
}
|
|
|
|
html += '<td>' + tableplane.icao + '</td>';
|
|
html += '<td>' + tableplane.flight + '</td>';
|
|
if (tableplane.squawk != '0000' ) {
|
|
html += '<td align="right">' + tableplane.squawk + '</td>';
|
|
} else {
|
|
html += '<td align="right"> </td>';
|
|
}
|
|
|
|
if (Metric) {
|
|
html += '<td align="right">' + Math.round(tableplane.altitude / 3.2828) + '</td>';
|
|
html += '<td align="right">' + Math.round(tableplane.speed * 1.852) + '</td>';
|
|
} else {
|
|
html += '<td align="right">' + tableplane.altitude + '</td>';
|
|
html += '<td align="right">' + tableplane.speed + '</td>';
|
|
}
|
|
|
|
html += '<td align="right">';
|
|
if (tableplane.vTrack) {
|
|
html += normalizeTrack(tableplane.track, tableplane.vTrack)[2];
|
|
// html += ' (' + normalizeTrack(tableplane.track, tableplane.vTrack)[1] + ')';
|
|
} else {
|
|
html += ' ';
|
|
}
|
|
html += '</td>';
|
|
html += '<td align="right">' + tableplane.messages + '</td>';
|
|
html += '<td align="right">' + tableplane.seen + '</td>';
|
|
html += '</tr>';
|
|
}
|
|
}
|
|
html += '</tbody></table>';
|
|
|
|
document.getElementById('planes_table').innerHTML = html;
|
|
|
|
if (SpecialSquawk) {
|
|
$('#SpecialSquawkWarning').css('display', 'inline');
|
|
} else {
|
|
$('#SpecialSquawkWarning').css('display', 'none');
|
|
}
|
|
|
|
// Click event for table
|
|
$('#planes_table').find('tr').click( function(){
|
|
var hex = $(this).find('td:first').text();
|
|
if (hex != "ICAO") {
|
|
selectPlaneByHex(hex);
|
|
refreshTableInfo();
|
|
refreshSelected();
|
|
}
|
|
});
|
|
|
|
sortTable("tableinfo");
|
|
}
|
|
|
|
// Credit goes to a co-worker that needed a similar functions for something else
|
|
// we get a copy of it free ;)
|
|
function setASC_DESC(iCol) {
|
|
if(iSortCol==iCol) {
|
|
bSortASC=!bSortASC;
|
|
} else {
|
|
bSortASC=bDefaultSortASC;
|
|
}
|
|
}
|
|
|
|
function sortTable(szTableID,iCol) {
|
|
//if iCol was not provided, and iSortCol is not set, assign default value
|
|
if (typeof iCol==='undefined'){
|
|
if(iSortCol!=-1){
|
|
var iCol=iSortCol;
|
|
} else {
|
|
var iCol=iDefaultSortCol;
|
|
}
|
|
}
|
|
|
|
//retrieve passed table element
|
|
var oTbl=document.getElementById(szTableID).tBodies[0];
|
|
var aStore=[];
|
|
|
|
//If supplied col # is greater than the actual number of cols, set sel col = to last col
|
|
if (typeof oTbl.rows[0] !== 'undefined' && oTbl.rows[0].cells.length <= iCol) {
|
|
iCol=(oTbl.rows[0].cells.length-1);
|
|
}
|
|
|
|
//store the col #
|
|
iSortCol=iCol;
|
|
|
|
//determine if we are delaing with numerical, or alphanumeric content
|
|
var bNumeric = false;
|
|
if ((typeof oTbl.rows[0] !== 'undefined') &&
|
|
(!isNaN(parseFloat(oTbl.rows[0].cells[iSortCol].textContent ||
|
|
oTbl.rows[0].cells[iSortCol].innerText)))) {
|
|
bNumeric = true;
|
|
}
|
|
|
|
//loop through the rows, storing each one inro aStore
|
|
for (var i=0,iLen=oTbl.rows.length;i<iLen;i++){
|
|
var oRow=oTbl.rows[i];
|
|
vColData=bNumeric?parseFloat(oRow.cells[iSortCol].textContent||oRow.cells[iSortCol].innerText):String(oRow.cells[iSortCol].textContent||oRow.cells[iSortCol].innerText);
|
|
aStore.push([vColData,oRow]);
|
|
}
|
|
|
|
//sort aStore ASC/DESC based on value of bSortASC
|
|
if (bNumeric) { //numerical sort
|
|
aStore.sort(function(x,y){return bSortASC?x[0]-y[0]:y[0]-x[0];});
|
|
} else { //alpha sort
|
|
aStore.sort();
|
|
if(!bSortASC) {
|
|
aStore.reverse();
|
|
}
|
|
}
|
|
|
|
//rewrite the table rows to the passed table element
|
|
for(var i=0,iLen=aStore.length;i<iLen;i++){
|
|
oTbl.appendChild(aStore[i][1]);
|
|
}
|
|
aStore=null;
|
|
}
|
|
|
|
function selectPlaneByHex(hex) {
|
|
// If SelectedPlane has something in it, clear out the selected
|
|
if (SelectedPlane != null) {
|
|
Planes[SelectedPlane].is_selected = false;
|
|
Planes[SelectedPlane].funcClearLine();
|
|
Planes[SelectedPlane].markerColor = MarkerColor;
|
|
// If the selected has a marker, make it not stand out
|
|
if (Planes[SelectedPlane].marker) {
|
|
Planes[SelectedPlane].marker.setIcon(Planes[SelectedPlane].funcGetIcon());
|
|
}
|
|
}
|
|
|
|
// If we are clicking the same plane, we are deselected it.
|
|
if (String(SelectedPlane) != String(hex)) {
|
|
// Assign the new selected
|
|
SelectedPlane = hex;
|
|
Planes[SelectedPlane].is_selected = true;
|
|
// If the selected has a marker, make it stand out
|
|
if (Planes[SelectedPlane].marker) {
|
|
Planes[SelectedPlane].funcUpdateLines();
|
|
Planes[SelectedPlane].marker.setIcon(Planes[SelectedPlane].funcGetIcon());
|
|
}
|
|
} else {
|
|
SelectedPlane = null;
|
|
}
|
|
refreshSelected();
|
|
refreshTableInfo();
|
|
}
|
|
|
|
function resetMap() {
|
|
// Reset localStorage values
|
|
localStorage['CenterLat'] = CONST_CENTERLAT;
|
|
localStorage['CenterLon'] = CONST_CENTERLON;
|
|
localStorage['ZoomLvl'] = CONST_ZOOMLVL;
|
|
|
|
// Try to read values from localStorage else use CONST_s
|
|
CenterLat = Number(localStorage['CenterLat']) || CONST_CENTERLAT;
|
|
CenterLon = Number(localStorage['CenterLon']) || CONST_CENTERLON;
|
|
ZoomLvl = Number(localStorage['ZoomLvl']) || CONST_ZOOMLVL;
|
|
|
|
// Set and refresh
|
|
GoogleMap.setZoom(parseInt(ZoomLvl));
|
|
GoogleMap.setCenter(new google.maps.LatLng(parseFloat(CenterLat), parseFloat(CenterLon)));
|
|
|
|
if (SelectedPlane) {
|
|
selectPlaneByHex(SelectedPlane);
|
|
}
|
|
|
|
refreshSelected();
|
|
refreshTableInfo();
|
|
}
|
|
|
|
function drawCircle(marker, distance) {
|
|
if (typeof distance === 'undefined') {
|
|
return false;
|
|
|
|
if (!(!isNaN(parseFloat(distance)) && isFinite(distance)) || distance < 0) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
distance *= 1000.0;
|
|
if (!Metric) {
|
|
distance *= 1.852;
|
|
}
|
|
|
|
// Add circle overlay and bind to marker
|
|
var circle = new google.maps.Circle({
|
|
map: GoogleMap,
|
|
radius: distance, // In meters
|
|
fillOpacity: 0.0,
|
|
strokeWeight: 1,
|
|
strokeOpacity: 0.3
|
|
});
|
|
circle.bindTo('center', marker, 'position');
|
|
}
|