Merge remote-tracking branch 'upstream/master' into net-cleanups

This commit is contained in:
Oliver Jowett 2014-10-31 17:58:03 +00:00
commit 29d1e53f9f
14 changed files with 287 additions and 73 deletions

Binary file not shown.

View file

@ -406,6 +406,7 @@ void showHelp(void) {
"--net Enable networking\n"
"--modeac Enable decoding of SSR Modes 3/A & 3/C\n"
"--net-only Enable just networking, no RTL device or file used\n"
"--net-bind-address <ip> IP address to bind to (default: Any; Use 127.0.0.1 for private)\n"
"--net-http-port <port> HTTP server port (default: 8080)\n"
"--net-ri-port <port> TCP raw input listen port (default: 30001)\n"
"--net-ro-port <port> TCP raw output listen port (default: 30002)\n"
@ -715,6 +716,8 @@ int main(int argc, char **argv) {
Modes.net_output_beast_port = atoi(argv[++j]);
} else if (!strcmp(argv[j],"--net-bi-port") && more) {
Modes.net_input_beast_port = atoi(argv[++j]);
} else if (!strcmp(argv[j],"--net-bind-address") && more) {
Modes.net_bind_address = strdup(argv[++j]);
} else if (!strcmp(argv[j],"--net-http-port") && more) {
Modes.net_http_port = atoi(argv[++j]);
} else if (!strcmp(argv[j],"--net-sbs-port") && more) {

View file

@ -131,6 +131,10 @@ SOURCE=.\winstubs.h
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# Begin Source File
SOURCE=.\Dump1090.rc
# End Source File
# End Group
# Begin Group "Library Files"

View file

@ -37,7 +37,7 @@
// MinorVer changes when additional features are added, but not for bug fixes (range 00-99)
// DayDate & Year changes for all changes, including for bug fixes. It represent the release date of the update
//
#define MODES_DUMP1090_VERSION "1.09.0608.14"
#define MODES_DUMP1090_VERSION "1.10.3010.14"
// ============================= Include files ==========================
@ -310,6 +310,7 @@ struct { // Internal state
int net_input_raw_port; // Raw input TCP port
int net_output_beast_port; // Beast output TCP port
int net_input_beast_port; // Beast input TCP port
char *net_bind_address; // Bind address
int net_http_port; // HTTP port
int net_sndbuf_size; // TCP output buffer size (64Kb * 2^n)
int quiet; // Suppress stdout

115
dump1090.rc Normal file
View file

@ -0,0 +1,115 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#define APSTUDIO_HIDDEN_SYMBOLS
#include "windows.h"
#undef APSTUDIO_HIDDEN_SYMBOLS
#include "ntverp.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,10,2910,14
PRODUCTVERSION 1,10,2910,14
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x3L
FILESUBTYPE 0x7L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "Dump1090 for Win32 \0"
VALUE "CompanyName", "\0"
VALUE "FileDescription", "Mode A/C/S decoder for RTL Dongles\0"
VALUE "FileVersion", "1, 10, 2910, 14\0"
VALUE "InternalName", "DUMP1090.EXE\0"
VALUE "LegalCopyright", "Copyright © 2012 by Salvatore Sanfilippo <antirez@gmail.com>\r\nCopyright © 2014 by Malcolm Robb <support@attavionics.com>\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "DUMP1090.EXE\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "DUMP1090\0"
VALUE "ProductVersion", "1, 10, 2910, 14\0"
VALUE "SpecialBuild", "\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // !_MAC
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
"#include ""windows.h""\r\n"
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
"#include ""ntverp.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

107
mode_s.c
View file

@ -1456,46 +1456,75 @@ int detectOutOfPhase(uint16_t *pPreamble) {
if (pPreamble[-1] > pPreamble[1]/3) return -1;
return 0;
}
uint16_t clamped_scale(uint16_t v, uint16_t scale) {
uint32_t scaled = (uint32_t)v * scale / 16384;
if (scaled > 65535) return 65535;
return (uint16_t) scaled;
}
// This function decides whether we are sampling early or late,
// and by approximately how much, by looking at the energy in
// preamble bits before and after the expected pulse locations.
//
//=========================================================================
//
// This function does not really correct the phase of the message, it just
// applies a transformation to the first sample representing a given bit:
//
// If the previous bit was one, we amplify it a bit.
// If the previous bit was zero, we decrease it a bit.
//
// This simple transformation makes the message a bit more likely to be
// correctly decoded for out of phase messages:
//
// When messages are out of phase there is more uncertainty in
// sequences of the same bit multiple times, since 11111 will be
// transmitted as continuously altering magnitude (high, low, high, low...)
//
// However because the message is out of phase some part of the high
// is mixed in the low part, so that it is hard to distinguish if it is
// a zero or a one.
//
// However when the message is out of phase passing from 0 to 1 or from
// 1 to 0 happens in a very recognizable way, for instance in the 0 -> 1
// transition, magnitude goes low, high, high, low, and one of of the
// two middle samples the high will be *very* high as part of the previous
// or next high signal will be mixed there.
//
// Applying our simple transformation we make more likely if the current
// bit is a zero, to detect another zero. Symmetrically if it is a one
// it will be more likely to detect a one because of the transformation.
// In this way similar levels will be interpreted more likely in the
// correct way.
// It then deals with one sample pair at a time, comparing samples
// to make a decision about the bit value. Based on this decision it
// modifies the sample value of the *adjacent* sample which will
// contain some of the energy from the bit we just inspected.
//
// pPayload[0] should be the start of the preamble,
// pPayload[-1 .. MODES_PREAMBLE_SAMPLES + MODES_LONG_MSG_SAMPLES - 1] should be accessible.
// pPayload[MODES_PREAMBLE_SAMPLES .. MODES_PREAMBLE_SAMPLES + MODES_LONG_MSG_SAMPLES - 1] will be updated.
void applyPhaseCorrection(uint16_t *pPayload) {
int j;
for (j = 0; j < MODES_LONG_MSG_SAMPLES; j += 2, pPayload += 2) {
if (pPayload[0] > pPayload[1]) { // One
pPayload[2] = (pPayload[2] * 5) / 4;
} else { // Zero
pPayload[2] = (pPayload[2] * 4) / 5;
// we expect 1 bits at 0, 2, 7, 9
// and 0 bits at -1, 1, 3, 4, 5, 6, 8, 10, 11, 12, 13, 14
// use bits -1,6 for early detection (bit 0/7 arrived a little early, our sample period starts after the bit phase so we include some of the next bit)
// use bits 3,10 for late detection (bit 2/9 arrived a little late, our sample period starts before the bit phase so we include some of the last bit)
uint32_t onTime = (pPayload[0] + pPayload[2] + pPayload[7] + pPayload[9]);
uint32_t early = (pPayload[-1] + pPayload[6]) << 1;
uint32_t late = (pPayload[3] + pPayload[10]) << 1;
if (early > late) {
// Our sample period starts late and so includes some of the next bit.
uint16_t scaleUp = 16384 + 16384 * early / (early + onTime); // 1 + early / (early+onTime)
uint16_t scaleDown = 16384 - 16384 * early / (early + onTime); // 1 - early / (early+onTime)
// trailing bits are 0; final data sample will be a bit low.
pPayload[MODES_PREAMBLE_SAMPLES + MODES_LONG_MSG_SAMPLES - 1] =
clamped_scale(pPayload[MODES_PREAMBLE_SAMPLES + MODES_LONG_MSG_SAMPLES - 1], scaleUp);
for (j = MODES_PREAMBLE_SAMPLES + MODES_LONG_MSG_SAMPLES - 2; j > MODES_PREAMBLE_SAMPLES; j -= 2) {
if (pPayload[j] > pPayload[j+1]) {
// x [1 0] y
// x overlapped with the "1" bit and is slightly high
pPayload[j-1] = clamped_scale(pPayload[j-1], scaleDown);
} else {
// x [0 1] y
// x overlapped with the "0" bit and is slightly low
pPayload[j-1] = clamped_scale(pPayload[j-1], scaleUp);
}
}
} else {
// Our sample period starts early and so includes some of the previous bit.
uint16_t scaleUp = 16384 + 16384 * late / (late + onTime); // 1 + late / (late+onTime)
uint16_t scaleDown = 16384 - 16384 * late / (late + onTime); // 1 - late / (late+onTime)
// leading bits are 0; first data sample will be a bit low.
pPayload[MODES_PREAMBLE_SAMPLES] = clamped_scale(pPayload[MODES_PREAMBLE_SAMPLES], scaleUp);
for (j = MODES_PREAMBLE_SAMPLES; j < MODES_PREAMBLE_SAMPLES + MODES_LONG_MSG_SAMPLES - 2; j += 2) {
if (pPayload[j] > pPayload[j+1]) {
// x [1 0] y
// y overlapped with the "0" bit and is slightly low
pPayload[j+2] = clamped_scale(pPayload[j+2], scaleUp);
} else {
// x [0 1] y
// y overlapped with the "1" bit and is slightly high
pPayload[j+2] = clamped_scale(pPayload[j+2], scaleDown);
}
}
}
}
@ -1509,7 +1538,7 @@ void applyPhaseCorrection(uint16_t *pPayload) {
void detectModeS(uint16_t *m, uint32_t mlen) {
struct modesMessage mm;
unsigned char msg[MODES_LONG_MSG_BYTES], *pMsg;
uint16_t aux[MODES_LONG_MSG_SAMPLES];
uint16_t aux[MODES_PREAMBLE_SAMPLES+MODES_LONG_MSG_SAMPLES+1];
uint32_t j;
int use_correction = 0;
@ -1631,10 +1660,10 @@ void detectModeS(uint16_t *m, uint32_t mlen) {
// If the previous attempt with this message failed, retry using
// magnitude correction
// Make a copy of the Payload, and phase correct the copy
memcpy(aux, pPayload, sizeof(aux));
applyPhaseCorrection(aux);
memcpy(aux, &pPreamble[-1], sizeof(aux));
applyPhaseCorrection(&aux[1]);
Modes.stat_out_of_phase++;
pPayload = aux;
pPayload = &aux[1 + MODES_PREAMBLE_SAMPLES];
// TODO ... apply other kind of corrections
}

View file

@ -86,7 +86,7 @@ void modesInitNet(void) {
for (j = 0; j < MODES_NET_SERVICES_NUM; j++) {
services[j].enabled = (services[j].port != 0);
if (services[j].enabled) {
int s = anetTcpServer(Modes.aneterr, services[j].port, NULL);
int s = anetTcpServer(Modes.aneterr, services[j].port, Modes.net_bind_address);
if (s == -1) {
fprintf(stderr, "Error opening the listening port %d (%s): %s\n",
services[j].port, services[j].descr, Modes.aneterr);
@ -159,7 +159,7 @@ struct client * modesAcceptClients(void) {
//
// On error free the client, collect the structure, adjust maxfd if needed.
//
void modesFreeClient(struct client *c) {
void modesCloseClient(struct client *c) {
int j;
// Clean up, but defer removing from the list until modesNetCleanup().
@ -200,7 +200,7 @@ static void flushWrites(struct net_writer *writer) {
int nwritten = send(c->fd, writer->data, writer->dataUsed, 0 );
#endif
if (nwritten != writer->dataUsed) {
modesFreeClient(c);
modesCloseClient(c);
}
}
}
@ -744,6 +744,7 @@ int handleHTTPRequest(struct client *c, char *p) {
char hdr[512];
int clen, hdrlen;
int httpver, keepalive;
int statuscode = 500;
char *url, *content;
char ctype[48];
char getFile[1024];
@ -756,11 +757,12 @@ int handleHTTPRequest(struct client *c, char *p) {
httpver = (strstr(p, "HTTP/1.1") != NULL) ? 11 : 10;
if (httpver == 10) {
// HTTP 1.0 defaults to close, unless otherwise specified.
keepalive = strstr(p, "Connection: keep-alive") != NULL;
//keepalive = strstr(p, "Connection: keep-alive") != NULL;
} else if (httpver == 11) {
// HTTP 1.1 defaults to keep-alive, unless close is specified.
keepalive = strstr(p, "Connection: close") == NULL;
//keepalive = strstr(p, "Connection: close") == NULL;
}
keepalive = 0;
// Identify he URL.
p = strchr(p,' ');
@ -785,22 +787,35 @@ int handleHTTPRequest(struct client *c, char *p) {
// "/" -> Our google map application.
// "/data.json" -> Our ajax request to update planes.
if (strstr(url, "/data.json")) {
statuscode = 200;
content = aircraftsToJson(&clen);
//snprintf(ctype, sizeof ctype, MODES_CONTENT_TYPE_JSON);
} else {
struct stat sbuf;
int fd = -1;
char *rp, *hrp;
if (stat(getFile, &sbuf) != -1 && (fd = open(getFile, O_RDONLY)) != -1) {
content = (char *) malloc(sbuf.st_size);
if (read(fd, content, sbuf.st_size) == -1) {
snprintf(content, sbuf.st_size, "Error reading from file: %s", strerror(errno));
rp = realpath(getFile, NULL);
hrp = realpath(HTMLPATH, NULL);
hrp = (hrp ? hrp : HTMLPATH);
clen = -1;
content = strdup("Server error occured");
if (rp && (!strncmp(hrp, rp, strlen(hrp)))) {
if (stat(getFile, &sbuf) != -1 && (fd = open(getFile, O_RDONLY)) != -1) {
content = (char *) realloc(content, sbuf.st_size);
if (read(fd, content, sbuf.st_size) != -1) {
clen = sbuf.st_size;
statuscode = 200;
}
}
clen = sbuf.st_size;
} else {
char buf[128];
clen = snprintf(buf,sizeof(buf),"Error opening HTML file: %s", strerror(errno));
content = strdup(buf);
errno = ENOENT;
}
if (clen < 0) {
content = realloc(content, 128);
clen = snprintf(content, 128,"Error opening HTML file: %s", strerror(errno));
statuscode = 404;
}
if (fd != -1) {
@ -824,7 +839,7 @@ int handleHTTPRequest(struct client *c, char *p) {
// Create the header and send the reply
hdrlen = snprintf(hdr, sizeof(hdr),
"HTTP/1.1 200 OK\r\n"
"HTTP/1.1 %d \r\n"
"Server: Dump1090\r\n"
"Content-Type: %s\r\n"
"Connection: %s\r\n"
@ -832,6 +847,7 @@ int handleHTTPRequest(struct client *c, char *p) {
"Cache-Control: no-cache, must-revalidate\r\n"
"Expires: Sat, 26 Jul 1997 05:00:00 GMT\r\n"
"\r\n",
statuscode,
ctype,
keepalive ? "keep-alive" : "close",
clen);
@ -899,17 +915,25 @@ void modesReadFromClient(struct client *c, char *sep,
if (nread != left) {
bContinue = 0;
}
#ifndef _WIN32
if ( (nread < 0 && errno != EAGAIN && errno != EWOULDBLOCK) || nread == 0 ) { // Error, or end of file
#else
if ( (nread < 0) && (errno != EWOULDBLOCK)) { // Error, or end of file
#endif
modesFreeClient(c);
if (nread == 0) { // End of file
modesCloseClient(c);
return;
}
if (nread <= 0) {
break; // Serve next client
#ifndef _WIN32
if (nread < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) { // No data available (not really an error)
#else
if (nread < 0 && errno == EWOULDBLOCK) { // No data available (not really an error)
#endif
return;
}
if (nread < 0) { // Other errors
modesCloseClient(c);
return;
}
c->buflen += nread;
// Always null-term so we are free to use strstr() (it won't affect binary case)
@ -952,7 +976,7 @@ void modesReadFromClient(struct client *c, char *sep,
}
// Have a 0x1a followed by 1, 2 or 3 - pass message less 0x1a to handler.
if (handler(c, s)) {
modesFreeClient(c);
modesCloseClient(c);
return;
}
fullmsg = 1;
@ -968,7 +992,7 @@ void modesReadFromClient(struct client *c, char *sep,
while ((e = strstr(s, sep)) != NULL) { // end of first message if found
*e = '\0'; // The handler expects null terminated strings
if (handler(c, s)) { // Pass message to handler.
modesFreeClient(c); // Handler returns 1 on error to signal we .
modesCloseClient(c); // Handler returns 1 on error to signal we .
return; // should close the client connection
}
s = e + strlen(sep); // Move to start of next message
@ -980,7 +1004,7 @@ void modesReadFromClient(struct client *c, char *sep,
c->buflen = &(c->buf[c->buflen]) - s; // Update the unprocessed buffer length
memmove(c->buf, s, c->buflen); // Move what's remaining to the start of the buffer
} else { // If no message was decoded process the next client
break;
return;
}
}
}

View file

@ -20,6 +20,7 @@ CONST_ZOOMLVL = 5;
// The default marker color
MarkerColor = "rgb(127, 127, 127)";
SelectedColor = "rgb(225, 225, 225)";
StaleColor = "rgb(190, 190, 190)";
// -- Site Settings ---------------------------------------
SiteShow = false; // true or false

View file

@ -1,10 +1,11 @@
<html>
<head>
<meta charset="utf-8"/>
<link rel="stylesheet" type="text/css" href="style.css" />
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?sensor=false&libraries=geometry"></script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?sensor=false&amp;libraries=geometry"></script>
<script type="text/javascript" src="config.js"></script>
<script type="text/javascript" src="planeObject.js"></script>
<script type="text/javascript" src="options.js"></script>
@ -13,6 +14,7 @@
<script type="text/javascript" src="coolclock/excanvas.js"></script>
<script type="text/javascript" src="coolclock/coolclock.js"></script>
<script type="text/javascript" src="coolclock/moreskins.js"></script>
<title>DUMP1090</title>
</head>
<body onload="initialize()">
<div id="dialog-modal" title="Basic modal dialog" style="display:none;">

View file

@ -53,10 +53,16 @@ var planeObject = {
// Should create an icon for us to use on the map...
funcGetIcon : function() {
this.markerColor = MarkerColor;
// If this marker is selected we should make it lighter than the rest.
if (this.is_selected == true) {
this.markerColor = SelectedColor;
}
// If we have not seen a recent update, change color
if (this.seen > 15) {
this.markerColor = StaleColor;
}
// Plane marker
var baseSvg = {

View file

@ -267,8 +267,10 @@ function refreshSelected() {
} else if (selected && selected.squawk == 7700) { // General Emergency
html += '&nbsp;<span class="squawk7700">&nbsp;Squawking: General Emergency&nbsp;</span>';
} else if (selected && selected.flight != '') {
html += '&nbsp;<a href="http://fr24.com/'+selected.flight+'" target="_blank">[FR24]</a>';
html += '&nbsp;<a href="http://www.flightstats.com/go/FlightStatus/flightStatusByFlight.do?';
html += 'flightNumber='+selected.flight+'" target="_blank">[FlightStats]</a>';
html += '&nbsp;<a href="http://flightaware.com/live/flight/'+selected.flight+'" target="_blank">[FlightAware]</a>';
}
html += '<td></tr>';
@ -330,12 +332,12 @@ function refreshSelected() {
dist /= 1852;
}
dist = (Math.round((dist)*10)/10).toFixed(1);
html += '<tr><td colspan="' + columns + '">Distance from Site: ' + dist +
html += '<tr><td colspan="' + columns + '" align="center">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 ' +
html += '<tr><td colspan="' + columns + '" align="center">Distance from Site: n/a ' +
(Metric ? ' km' : ' NM') + '</td></tr>';
} else {
html += 'n/a</td></tr>';
@ -403,11 +405,16 @@ function refreshTableInfo() {
'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\');" ' +
// Add distance column header to table if site coordinates are provided
if (SiteShow && (typeof SiteLat !== 'undefined' || typeof SiteLon !== 'undefined')) {
html += '<td onclick="setASC_DESC(\'5\');sortTable(\'tableinfo\',\'5\');" ' +
'align="right">Distance</td>';
}
html += '<td onclick="setASC_DESC(\'5\');sortTable(\'tableinfo\',\'6\');" ' +
'align="right">Track</td>';
html += '<td onclick="setASC_DESC(\'6\');sortTable(\'tableinfo\',\'6\');" ' +
html += '<td onclick="setASC_DESC(\'6\');sortTable(\'tableinfo\',\'7\');" ' +
'align="right">Msgs</td>';
html += '<td onclick="setASC_DESC(\'7\');sortTable(\'tableinfo\',\'7\');" ' +
html += '<td onclick="setASC_DESC(\'7\');sortTable(\'tableinfo\',\'8\');" ' +
'align="right">Seen</td></thead><tbody>';
for (var tablep in Planes) {
var tableplane = Planes[tablep]
@ -451,6 +458,25 @@ function refreshTableInfo() {
html += '<td align="right">' + tableplane.altitude + '</td>';
html += '<td align="right">' + tableplane.speed + '</td>';
}
// Add distance column to table if site coordinates are provided
if (SiteShow && (typeof SiteLat !== 'undefined' || typeof SiteLon !== 'undefined')) {
html += '<td align="right">';
if (tableplane.vPosition) {
var siteLatLon = new google.maps.LatLng(SiteLat, SiteLon);
var planeLatLon = new google.maps.LatLng(tableplane.latitude, tableplane.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 += dist;
} else {
html += '0';
}
html += '</td>';
}
html += '<td align="right">';
if (tableplane.vTrack) {
@ -503,6 +529,8 @@ function sortTable(szTableID,iCol) {
if (typeof iCol==='undefined'){
if(iSortCol!=-1){
var iCol=iSortCol;
} else if (SiteShow && (typeof SiteLat !== 'undefined' || typeof SiteLon !== 'undefined')) {
var iCol=5;
} else {
var iCol=iDefaultSortCol;
}

View file

@ -1,6 +1,6 @@
html, body {
margin: 0; padding: 0; background-color: #ffffff; font-family: Tahoma, Sans-Serif;
font-size: 10pt; overflow: auto;
font-size: 10pt; overflow: auto; height: 100%;
}
div#map_container { float: left; width: 100%; height: 100%; }
div#map_canvas { height: 100%; margin-right: 420px; }

View file

@ -72,9 +72,10 @@ _inline double trunc(double d) {return (d>0) ? floor(d):ceil(d) ;}
//usleep works in microseconds, and isn't supported in Windows. This will do for our use.
_inline void usleep(UINT32 ulSleep) {Sleep(ulSleep/1000);}
_inline uint64_t strtoll(const char *p, void *e, UINT32 base) {return _atoi64(p);}
_inline int inet_aton(const char * cp, DWORD * ulAddr) { *ulAddr = inet_addr(cp); return 0;}
_inline int inet_aton(const char * cp, DWORD * ulAddr) { *ulAddr = inet_addr(cp); return (INADDR_NONE != *ulAddr);}
#define snprintf _snprintf
#define vsnprintf _vsnprintf
#define realpath(N,R) _fullpath((R),(N),_MAX_PATH)
_inline void cls() {
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);