Show altitude colors in plane track lines
Show altitude color key on map Correctly handle retina images with CSS
BIN
public_html/images/altitude_legend.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
public_html/images/altitude_legend@2x.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
public_html/images/altitude_legend@3x.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
public_html/images/box-checked@2x.png
Normal file
After Width: | Height: | Size: 292 B |
BIN
public_html/images/box-checked@3x.png
Normal file
After Width: | Height: | Size: 325 B |
BIN
public_html/images/box-empty@2x.png
Normal file
After Width: | Height: | Size: 232 B |
BIN
public_html/images/box-empty@3x.png
Normal file
After Width: | Height: | Size: 281 B |
|
@ -242,12 +242,15 @@
|
|||
|
||||
<div id="map_container">
|
||||
<div id="map_canvas"></div>
|
||||
<div id="toggle_sidebar_control" class="ol-unselectable ol-control">
|
||||
<button id="toggle_sidebar_button" class="hide_sidebar" title="Toggle Sidebar"></button>
|
||||
</div>
|
||||
<div id="expand_sidebar_control" class="ol-unselectable ol-control">
|
||||
<button id="expand_sidebar_button" title="Expand Sidebar"></button>
|
||||
</div>
|
||||
<div id="toggle_sidebar_control" class="ol-unselectable ol-control">
|
||||
<button id="toggle_sidebar_button" class="hide_sidebar" title="Toggle Sidebar"></button>
|
||||
</div>
|
||||
<div id="expand_sidebar_control" class="ol-unselectable ol-control">
|
||||
<button id="expand_sidebar_button" title="Expand Sidebar"></button>
|
||||
</div>
|
||||
<div id="altitude_chart" class="ol-unselectable ol-control">
|
||||
<button id="altitude_chart_button"></button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="sidebar_container">
|
||||
<div id="splitter" class="ui-resizable-handle ui-resizable-w"></div>
|
||||
|
|
|
@ -115,7 +115,8 @@ PlaneObject.prototype.updateTrack = function(estimate_time) {
|
|||
head_update: this.last_position_time,
|
||||
tail_update: this.last_position_time,
|
||||
estimated: false,
|
||||
ground: (this.altitude === "ground")
|
||||
ground: (this.altitude === "ground"),
|
||||
altitude: this.altitude
|
||||
};
|
||||
this.track_linesegs.push(newseg);
|
||||
this.history_size ++;
|
||||
|
@ -176,6 +177,7 @@ PlaneObject.prototype.updateTrack = function(estimate_time) {
|
|||
head_update: this.last_position_time,
|
||||
tail_update: this.last_position_time,
|
||||
estimated: false,
|
||||
altitude: this.altitude,
|
||||
ground: (this.altitude === "ground") });
|
||||
this.history_size += 3;
|
||||
return true;
|
||||
|
@ -236,33 +238,11 @@ PlaneObject.prototype.getMarkerColor = function() {
|
|||
|
||||
var h, s, l;
|
||||
|
||||
if (this.altitude === null) {
|
||||
h = ColorByAlt.unknown.h;
|
||||
s = ColorByAlt.unknown.s;
|
||||
l = ColorByAlt.unknown.l;
|
||||
} else if (this.altitude === "ground") {
|
||||
h = ColorByAlt.ground.h;
|
||||
s = ColorByAlt.ground.s;
|
||||
l = ColorByAlt.ground.l;
|
||||
} else {
|
||||
s = ColorByAlt.air.s;
|
||||
l = ColorByAlt.air.l;
|
||||
var colorArr = this.getAltitudeColor();
|
||||
|
||||
// find the pair of points the current altitude lies between,
|
||||
// and interpolate the hue between those points
|
||||
var hpoints = ColorByAlt.air.h;
|
||||
h = hpoints[0].val;
|
||||
for (var i = hpoints.length-1; i >= 0; --i) {
|
||||
if (this.altitude > hpoints[i].alt) {
|
||||
if (i == hpoints.length-1) {
|
||||
h = hpoints[i].val;
|
||||
} else {
|
||||
h = hpoints[i].val + (hpoints[i+1].val - hpoints[i].val) * (this.altitude - hpoints[i].alt) / (hpoints[i+1].alt - hpoints[i].alt)
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
h = colorArr[0];
|
||||
s = colorArr[1];
|
||||
l = colorArr[2];
|
||||
|
||||
// If we have not seen a recent position update, change color
|
||||
if (this.seen_pos > 15) {
|
||||
|
@ -300,6 +280,56 @@ PlaneObject.prototype.getMarkerColor = function() {
|
|||
return 'hsl(' + (h/5).toFixed(0)*5 + ',' + (s/5).toFixed(0)*5 + '%,' + (l/5).toFixed(0)*5 + '%)'
|
||||
}
|
||||
|
||||
PlaneObject.prototype.getAltitudeColor = function(altitude) {
|
||||
var h, s, l;
|
||||
|
||||
if (typeof altitude === 'undefined') {
|
||||
altitude = this.altitude;
|
||||
}
|
||||
|
||||
if (altitude === null) {
|
||||
h = ColorByAlt.unknown.h;
|
||||
s = ColorByAlt.unknown.s;
|
||||
l = ColorByAlt.unknown.l;
|
||||
} else if (this.altitude === "ground") {
|
||||
h = ColorByAlt.ground.h;
|
||||
s = ColorByAlt.ground.s;
|
||||
l = ColorByAlt.ground.l;
|
||||
} else {
|
||||
s = ColorByAlt.air.s;
|
||||
l = ColorByAlt.air.l;
|
||||
|
||||
// find the pair of points the current altitude lies between,
|
||||
// and interpolate the hue between those points
|
||||
var hpoints = ColorByAlt.air.h;
|
||||
h = hpoints[0].val;
|
||||
for (var i = hpoints.length-1; i >= 0; --i) {
|
||||
if (altitude > hpoints[i].alt) {
|
||||
if (i == hpoints.length-1) {
|
||||
h = hpoints[i].val;
|
||||
} else {
|
||||
h = hpoints[i].val + (hpoints[i+1].val - hpoints[i].val) * (altitude - hpoints[i].alt) / (hpoints[i+1].alt - hpoints[i].alt)
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (h < 0) {
|
||||
h = (h % 360) + 360;
|
||||
} else if (h >= 360) {
|
||||
h = h % 360;
|
||||
}
|
||||
|
||||
if (s < 5) s = 5;
|
||||
else if (s > 95) s = 95;
|
||||
|
||||
if (l < 5) l = 5;
|
||||
else if (l > 95) l = 95;
|
||||
|
||||
return [h, s, l];
|
||||
}
|
||||
|
||||
PlaneObject.prototype.updateIcon = function() {
|
||||
var scaleFactor = Math.max(0.2, Math.min(1.2, 0.15 * Math.pow(1.25, ZoomLvl))).toFixed(1);
|
||||
|
||||
|
@ -500,6 +530,18 @@ PlaneObject.prototype.updateMarker = function(moved) {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
// return the styling of the lines based on altitude
|
||||
PlaneObject.prototype.altitudeLines = function(altitude) {
|
||||
var colorArr = this.getAltitudeColor(altitude);
|
||||
return new ol.style.Style({
|
||||
stroke: new ol.style.Stroke({
|
||||
color: 'hsl(' + (colorArr[0]/5).toFixed(0)*5 + ',' + (colorArr[1]/5).toFixed(0)*5 + '%,' + (colorArr[2]/5).toFixed(0)*5 + '%)',
|
||||
width: 2
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Update our planes tail line,
|
||||
PlaneObject.prototype.updateLines = function() {
|
||||
if (!this.selected)
|
||||
|
@ -542,7 +584,7 @@ PlaneObject.prototype.updateLines = function() {
|
|||
var lastfixed = lastseg.fixed.getCoordinateAt(1.0);
|
||||
var geom = new ol.geom.LineString([lastfixed, ol.proj.fromLonLat(this.position)]);
|
||||
this.elastic_feature = new ol.Feature(geom);
|
||||
this.elastic_feature.setStyle(this.altitude === 'ground' ? groundStyle : airStyle);
|
||||
this.elastic_feature.setStyle(this.altitudeLines(this.altitude));
|
||||
|
||||
if (oldElastic < 0) {
|
||||
PlaneTrailFeatures.push(this.elastic_feature);
|
||||
|
@ -557,10 +599,8 @@ PlaneObject.prototype.updateLines = function() {
|
|||
seg.feature = new ol.Feature(seg.fixed);
|
||||
if (seg.estimated) {
|
||||
seg.feature.setStyle(estimateStyle);
|
||||
} else if (seg.ground) {
|
||||
seg.feature.setStyle(groundStyle);
|
||||
} else {
|
||||
seg.feature.setStyle(airStyle);
|
||||
seg.feature.setStyle(this.altitudeLines(seg.altitude));
|
||||
}
|
||||
|
||||
PlaneTrailFeatures.push(seg.feature);
|
||||
|
|
|
@ -520,7 +520,7 @@ function initialize_map() {
|
|||
}),
|
||||
controls: [new ol.control.Zoom(),
|
||||
new ol.control.Rotate(),
|
||||
new ol.control.Attribution({collapsed: false}),
|
||||
new ol.control.Attribution({collapsed: true}),
|
||||
new ol.control.ScaleLine({units: DisplayUnits}),
|
||||
new ol.control.LayerSwitcher()
|
||||
],
|
||||
|
|
|
@ -53,34 +53,10 @@ html, body {
|
|||
|
||||
#toggle_sidebar_button.show_sidebar {
|
||||
background-image: url("images/table-icon.png");
|
||||
background-image:
|
||||
-webkit-image-set(
|
||||
"images/table-icon.png" 1x,
|
||||
"images/table-icon@2x.png" 2x,
|
||||
"images/table-icon@3x.png" 3x
|
||||
);
|
||||
background-image:
|
||||
-image-set(
|
||||
"images/table-icon.png" 1x,
|
||||
"images/table-icon@2x.png" 2x,
|
||||
"images/table-icon@3x.png" 3x
|
||||
);
|
||||
}
|
||||
|
||||
#toggle_sidebar_button.hide_sidebar {
|
||||
background-image: url("images/map-icon.png");
|
||||
background-image:
|
||||
-webkit-image-set(
|
||||
"images/map-icon.png" 1x,
|
||||
"images/map-icon@2x.png" 2x,
|
||||
"images/map-icon@3x.png" 3x
|
||||
);
|
||||
background-image:
|
||||
-image-set(
|
||||
"images/map-icon.png" 1x,
|
||||
"images/map-icon@2x.png" 2x,
|
||||
"images/map-icon@3x.png" 3x
|
||||
);
|
||||
}
|
||||
|
||||
#expand_sidebar_control {
|
||||
|
@ -104,18 +80,6 @@ html, body {
|
|||
|
||||
#expand_sidebar_button {
|
||||
background-image: url("images/table-icon.png");
|
||||
background-image:
|
||||
-webkit-image-set(
|
||||
"images/table-icon.png" 1x,
|
||||
"images/table-icon@2x.png" 2x,
|
||||
"images/table-icon@3x.png" 3x
|
||||
);
|
||||
background-image:
|
||||
-image-set(
|
||||
"images/table-icon.png" 1x,
|
||||
"images/table-icon@2x.png" 2x,
|
||||
"images/table-icon@3x.png" 3x
|
||||
);
|
||||
}
|
||||
|
||||
#sidebar_container {
|
||||
|
@ -140,34 +104,10 @@ html, body {
|
|||
background-color: transparent;
|
||||
border: none;
|
||||
background-image: url("images/column-adjust.png");
|
||||
background-image:
|
||||
-webkit-image-set(
|
||||
"images/column-adjust.png" 1x,
|
||||
"images/column-adjust@2x.png" 2x,
|
||||
"images/column-adjust@3x.png" 3x
|
||||
);
|
||||
background-image:
|
||||
-image-set(
|
||||
"images/column-adjust.png" 1x,
|
||||
"images/column-adjust@2x.png" 2x,
|
||||
"images/column-adjust@3x.png" 3x
|
||||
);
|
||||
}
|
||||
|
||||
.ol-zoom-in {
|
||||
background-image: url("images/zoom-in.png");
|
||||
background-image:
|
||||
-webkit-image-set(
|
||||
"images/zoom-in.png" 1x,
|
||||
"images/zoom-in@2x.png" 2x,
|
||||
"images/zoom-in@3x.png" 3x
|
||||
);
|
||||
background-image:
|
||||
-image-set(
|
||||
"images/zoom-in.png" 1x,
|
||||
"images/zoom-in@2x.png" 2x,
|
||||
"images/zoom-in@3x.png" 3x
|
||||
);
|
||||
color:transparent !important;
|
||||
width: 19px !important;
|
||||
height: 19px !important;
|
||||
|
@ -177,18 +117,6 @@ html, body {
|
|||
|
||||
.ol-zoom-out {
|
||||
background-image: url("images/zoom-out.png");
|
||||
background-image:
|
||||
-webkit-image-set(
|
||||
"images/zoom-out.png" 1x,
|
||||
"images/zoom-out@2x.png" 2x,
|
||||
"images/zoom-out@3x.png" 3x
|
||||
);
|
||||
background-image:
|
||||
-image-set(
|
||||
"images/zoom-out.png" 1x,
|
||||
"images/zoom-out@2x.png" 2x,
|
||||
"images/zoom-out@3x.png" 3x
|
||||
);
|
||||
color:transparent !important;
|
||||
width: 19px !important;
|
||||
height: 19px !important;
|
||||
|
@ -668,3 +596,81 @@ select.error, textarea.error, input.error {
|
|||
line-height: 20px;
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
#altitude_chart {
|
||||
float: right;
|
||||
width: 502px;
|
||||
height: 18px;
|
||||
right: 40px;
|
||||
bottom: 10px;
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
#altitude_chart_button {
|
||||
background-image: url('images/altitude_legend.png');
|
||||
background-color: transparent;
|
||||
width: 502px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
/* Retina 2x images */
|
||||
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
|
||||
#altitude_chart_button {
|
||||
background-image: url('images/altitude_legend@2x.png');
|
||||
}
|
||||
.settingsCheckboxChecked {
|
||||
background-image: url('images/box-checked@2x.png') !important;
|
||||
}
|
||||
.settingsCheckbox {
|
||||
background-image: url('images/box-empty@2x.png');
|
||||
}
|
||||
.ol-zoom-out {
|
||||
background-image: url("images/zoom-out@2x.png");
|
||||
}
|
||||
.ol-zoom-in {
|
||||
background-image: url("images/zoom-in@2x.png");
|
||||
}
|
||||
#splitter {
|
||||
background-image: url("images/column-adjust@2x.png");
|
||||
}
|
||||
#toggle_sidebar_button.show_sidebar {
|
||||
background-image: url("images/table-icon@2x.png");
|
||||
}
|
||||
#expand_sidebar_button {
|
||||
background-image: url("images/table-icon@2x.png");
|
||||
}
|
||||
#toggle_sidebar_button.hide_sidebar {
|
||||
background-image: url("images/map-icon@2x.png");
|
||||
}
|
||||
}
|
||||
|
||||
/* Retina 3x images */
|
||||
@media (-webkit-min-device-pixel-ratio: 3), (min-resolution: 192dpi) {
|
||||
#altitude_chart_button {
|
||||
background-image: url('images/altitude_legend@3x.png');
|
||||
}
|
||||
.settingsCheckboxChecked {
|
||||
background-image: url('images/box-checked@3x.png') !important;
|
||||
}
|
||||
.settingsCheckbox {
|
||||
background-image: url('images/box-empty@3x.png');
|
||||
}
|
||||
.ol-zoom-out {
|
||||
background-image: url("images/zoom-out@3x.png");
|
||||
}
|
||||
.ol-zoom-in {
|
||||
background-image: url("images/zoom-in@3x.png");
|
||||
}
|
||||
#splitter {
|
||||
background-image: url("images/column-adjust@3x.png");
|
||||
}
|
||||
#toggle_sidebar_button.show_sidebar {
|
||||
background-image: url("images/table-icon@3x.png");
|
||||
}
|
||||
#expand_sidebar_button {
|
||||
background-image: url("images/table-icon@3x.png");
|
||||
}
|
||||
#toggle_sidebar_button.hide_sidebar {
|
||||
background-image: url("images/map-icon@3x.png");
|
||||
}
|
||||
}
|