map: Split packet paths by digipeater, allow hiding individually
This commit is contained in:
parent
dc72da37f6
commit
9e863b8ec7
30
src/map.html
30
src/map.html
@ -15,11 +15,39 @@
|
|||||||
right: 0.5em;
|
right: 0.5em;
|
||||||
background-color: rgba(70, 115, 164, 0.7);
|
background-color: rgba(70, 115, 164, 0.7);
|
||||||
color: #eee;
|
color: #eee;
|
||||||
|
white-space: nowrap;
|
||||||
|
max-height: calc(100vh - 1em);
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
.layer-toggles > div {
|
||||||
|
margin: 0.5em;
|
||||||
|
margin-right: 1em;
|
||||||
}
|
}
|
||||||
.ol-control.layer-toggles:hover {
|
.ol-control.layer-toggles:hover {
|
||||||
background-color: rgba(0,60,136,0.7);
|
background-color: rgba(0,60,136,0.7);
|
||||||
}
|
}
|
||||||
.layer-toggles > label {
|
.layer-toggles > div > label {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.expand {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.expand + span::before {
|
||||||
|
content: '\25B6';
|
||||||
|
}
|
||||||
|
.expand:checked + span::before {
|
||||||
|
content: '\25BC';
|
||||||
|
}
|
||||||
|
.expand ~ .collapsible-content {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.expand:checked ~ .collapsible-content {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.collapsible-content {
|
||||||
|
margin-left: 0.8em;
|
||||||
|
}
|
||||||
|
.collapsible-content label {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
73
src/map.js
73
src/map.js
@ -1,12 +1,11 @@
|
|||||||
import 'ol/ol.css';
|
import 'ol/ol.css';
|
||||||
import {Map as olMap, View} from 'ol';
|
import {Map as olMap, View} from 'ol';
|
||||||
import {Control} from 'ol/control';
|
import {Control} from 'ol/control';
|
||||||
import {Tile as TileLayer, Vector as VectorLayer} from 'ol/layer';
|
import {Group as LayerGroup, Tile as TileLayer, Vector as VectorLayer} from 'ol/layer';
|
||||||
import {OSM, Vector as VectorSource} from 'ol/source';
|
import {OSM, Vector as VectorSource} from 'ol/source';
|
||||||
import Feature from 'ol/Feature';
|
import Feature from 'ol/Feature';
|
||||||
import {fromLonLat} from 'ol/proj';
|
import {fromLonLat} from 'ol/proj';
|
||||||
import {Icon, Fill, Stroke, Style, Text} from 'ol/style';
|
import {Circle as CircleStyle, Icon, Fill, Stroke, Style, Text} from 'ol/style';
|
||||||
import CircleStyle from 'ol/style/Circle';
|
|
||||||
import Projection from 'ol/proj/Projection';
|
import Projection from 'ol/proj/Projection';
|
||||||
import {LineString, Point} from 'ol/geom';
|
import {LineString, Point} from 'ol/geom';
|
||||||
|
|
||||||
@ -175,11 +174,9 @@ function plotPacketPaths(packets) {
|
|||||||
tile_layer.getSource().getProjection());
|
tile_layer.getSource().getProjection());
|
||||||
});
|
});
|
||||||
|
|
||||||
let packet_path_layer = new VectorLayer({
|
let packet_path_layers = new LayerGroup({title: "Packet Paths"});
|
||||||
title: "Packet Paths",
|
let layers_map = new Map();
|
||||||
source: new VectorSource(),
|
map.addLayer(packet_path_layers);
|
||||||
});
|
|
||||||
map.addLayer(packet_path_layer);
|
|
||||||
packets
|
packets
|
||||||
.filter(packet => packet.date > new Date("2018-07-14") && packet.date < new Date("2018-07-15"))
|
.filter(packet => packet.date > new Date("2018-07-14") && packet.date < new Date("2018-07-15"))
|
||||||
// filter by callsign
|
// filter by callsign
|
||||||
@ -192,13 +189,11 @@ function plotPacketPaths(packets) {
|
|||||||
if (digiPos.get(station) === undefined) {
|
if (digiPos.get(station) === undefined) {
|
||||||
console.log(station);
|
console.log(station);
|
||||||
}
|
}
|
||||||
let previous;
|
|
||||||
if (index === 0) {
|
// first point in path is originating station
|
||||||
previous = [packet.data.longitude, packet.data.latitude];
|
let previous = (index === 0) ?
|
||||||
}
|
[packet.data.longitude, packet.data.latitude] :
|
||||||
else {
|
digiPos.get(stations[index - 1]) || [0, 0];
|
||||||
previous = digiPos.get(stations[index - 1]) || [0, 0];
|
|
||||||
}
|
|
||||||
|
|
||||||
let pathFeature = new Feature(
|
let pathFeature = new Feature(
|
||||||
new LineString([previous, digiPos.get(station) || [0, 0]]));
|
new LineString([previous, digiPos.get(station) || [0, 0]]));
|
||||||
@ -211,7 +206,17 @@ function plotPacketPaths(packets) {
|
|||||||
{color: 'hsl(' + color + ', 60%, 60%)', width: 2}
|
{color: 'hsl(' + color + ', 60%, 60%)', width: 2}
|
||||||
)}));
|
)}));
|
||||||
|
|
||||||
packet_path_layer.getSource().addFeature(pathFeature);
|
if (!layers_map.has(station)) {
|
||||||
|
layers_map.set(station, new VectorLayer({
|
||||||
|
title: station,
|
||||||
|
source: new VectorSource(),
|
||||||
|
renderMode: 'image',
|
||||||
|
features: [pathFeature]
|
||||||
|
}));
|
||||||
|
packet_path_layers.getLayers().push(layers_map.get(station));
|
||||||
|
}
|
||||||
|
layers_map.get(station).getSource().addFeature(pathFeature);
|
||||||
|
|
||||||
pathFeature.getGeometry().transform(new Projection({code: "EPSG:4326"}),
|
pathFeature.getGeometry().transform(new Projection({code: "EPSG:4326"}),
|
||||||
tile_layer.getSource().getProjection());
|
tile_layer.getSource().getProjection());
|
||||||
});
|
});
|
||||||
@ -220,12 +225,11 @@ function plotPacketPaths(packets) {
|
|||||||
|
|
||||||
let element = document.createElement('div');
|
let element = document.createElement('div');
|
||||||
element.className = 'layer-toggles ol-unselectable ol-control';
|
element.className = 'layer-toggles ol-unselectable ol-control';
|
||||||
function render_layer_toggles(event) {
|
let inner = element.appendChild(document.createElement('div'));
|
||||||
event.map.getLayers().getArray()
|
|
||||||
.filter(layer => layer.get('title') !== undefined)
|
function layer_toggle(layer, parentElement) {
|
||||||
.forEach(layer => {
|
|
||||||
if (layer.toggle_element === undefined) {
|
if (layer.toggle_element === undefined) {
|
||||||
layer.toggle_element = element.appendChild(
|
layer.toggle_element = parentElement.appendChild(
|
||||||
document.createElement('label'));
|
document.createElement('label'));
|
||||||
|
|
||||||
let checkbox = layer.toggle_element.appendChild(
|
let checkbox = layer.toggle_element.appendChild(
|
||||||
@ -238,8 +242,35 @@ function render_layer_toggles(event) {
|
|||||||
layer.toggle_element.appendChild(
|
layer.toggle_element.appendChild(
|
||||||
document.createTextNode(layer.get('title')));
|
document.createTextNode(layer.get('title')));
|
||||||
}
|
}
|
||||||
|
return layer.toggle_element;
|
||||||
|
}
|
||||||
|
|
||||||
|
function render_layer_toggles(event) {
|
||||||
|
event.map.getLayers().getArray()
|
||||||
|
.filter(layer => layer.get('title') !== undefined)
|
||||||
|
.forEach(layer => {
|
||||||
|
console.log(layer.get('title'));
|
||||||
|
if (layer instanceof LayerGroup) {
|
||||||
|
if (layer.group_toggle === undefined) {
|
||||||
|
let label = layer.group_toggle = inner.appendChild(
|
||||||
|
document.createElement('label'));
|
||||||
|
let input = label.appendChild(document.createElement('input'));
|
||||||
|
input.type = 'checkbox';
|
||||||
|
input.className = "expand";
|
||||||
|
label.appendChild(document.createElement('span'));
|
||||||
|
layer_toggle(layer, label); // whole LayerGroup
|
||||||
|
let container = label.appendChild(document.createElement('div'));
|
||||||
|
container.className = 'collapsible-content';
|
||||||
|
layer.getLayers().forEach(
|
||||||
|
sublayer => layer_toggle(sublayer, container));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
layer_toggle(layer, inner);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let control = new Control({element: element,
|
let control = new Control({element: element,
|
||||||
render: render_layer_toggles});
|
render: render_layer_toggles});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user