From 16a4fff70887def76dca5e8e1bc9c93baa67be6d Mon Sep 17 00:00:00 2001 From: NatureFreshMilk Date: Thu, 25 Jul 2019 15:53:47 +0200 Subject: [PATCH] trainsignal overlay --- app/config.go | 2 + static/js/Overlaysetup.js | 10 ++ static/js/overlays/TrainsignalOverlay.js | 146 +++++++++++++++++++++++ 3 files changed, 158 insertions(+) create mode 100644 static/js/overlays/TrainsignalOverlay.js diff --git a/app/config.go b/app/config.go index a6352fb..72aa274 100644 --- a/app/config.go +++ b/app/config.go @@ -61,6 +61,7 @@ type MapObjectConfig struct { Fancyvend bool `json:"fancyvend"` ATM bool `json:"atm"` Train bool `json:"train"` + TrainSignal bool `json:"trainsignal"` Minecart bool `json:"minecart"` Locator bool `json:"locator"` } @@ -149,6 +150,7 @@ func ParseConfig(filename string) (*Config, error) { Fancyvend: true, ATM: true, Train: true, +TrainSignal: true, Minecart: false, Locator: false, } diff --git a/static/js/Overlaysetup.js b/static/js/Overlaysetup.js index 6e4dfde..5f71749 100644 --- a/static/js/Overlaysetup.js +++ b/static/js/Overlaysetup.js @@ -20,6 +20,7 @@ import ATMOverlay from './overlays/ATMOverlay.js'; import LocatorOverlay from './overlays/LocatorOverlay.js'; import BorderOverlay from './overlays/BorderOverlay.js'; import TrainOverlay from './overlays/TrainOverlay.js'; +import TrainsignalOverlay from './overlays/TrainsignalOverlay.js'; export default function(cfg, map, overlays, wsChannel, layerMgr){ @@ -155,11 +156,20 @@ export default function(cfg, map, overlays, wsChannel, layerMgr){ if (cfg.mapobjects.train) { overlays.Trains = new TrainOverlay(wsChannel, layerMgr); + if (isDefault("train")) { map.addLayer(overlays.Trains); } } + if (cfg.mapobjects.trainsignal) { + overlays.Trainsignals = new TrainsignalOverlay(wsChannel, layerMgr); + + if (isDefault("trainsignal")) { + map.addLayer(overlays.Trainsignals); + } + } + if (cfg.mapobjects.minecart) { overlays.Minecart = new MinecartOverlay(wsChannel, layerMgr); if (isDefault("minecart")) { diff --git a/static/js/overlays/TrainsignalOverlay.js b/static/js/overlays/TrainsignalOverlay.js new file mode 100644 index 0000000..566f9c8 --- /dev/null +++ b/static/js/overlays/TrainsignalOverlay.js @@ -0,0 +1,146 @@ + +export default L.LayerGroup.extend({ + initialize: function(wsChannel, layerMgr) { + L.LayerGroup.prototype.initialize.call(this); + + this.layerMgr = layerMgr; + this.wsChannel = wsChannel; + + this.currentObjects = {}; // name => marker + this.signals = []; + + this.reDraw = this.reDraw.bind(this); + this.onMinetestUpdate = this.onMinetestUpdate.bind(this); + + //update players all the time + this.wsChannel.addListener("minetest-info", function(info){ + this.signals = info.signals || []; + }.bind(this)); + }, + + createPopup: function(signal){ + var html = "Signal
"; + html += "State: " + signal.green + "
"; + + return html; + }, + + hashPos: function(x,y,z){ + return x + "/" + y + "/" + z; + }, + + getMaxDisplayedZoom: function(){ + return 10; + }, + + createMarker: function(signal){ + + var Icon = L.icon({ + iconUrl: "TODO", + + iconSize: [16, 16], + iconAnchor: [8, 8], + popupAnchor: [0, -16] + }); + + var marker = L.marker([signal.pos.z, signal.pos.x], {icon: Icon}); + marker.bindPopup(this.createPopup(signal)); + + return marker; + }, + + isSignalInCurrentLayer: function(signal){ + var mapLayer = this.layerMgr.getCurrentLayer(); + + return (signal.pos.y >= (mapLayer.from*16) && signal.pos.y <= (mapLayer.to*16)); + }, + + + onMinetestUpdate: function(/*info*/){ + + if (this.map.getZoom() < this.getMaxDisplayedZoom()) { + this.clearLayers(); + this.currentObjects = {}; + return; + } + + this.signals.forEach(signal => { + var isInLayer = this.isSignalInCurrentLayer(signal); + var signalId = this.hashPos(signal.pos.x, signal.pos.y, signal.pos.z); + + if (!isInLayer){ + if (this.currentObjects[signalId]){ + //signal is displayed and not on the layer anymore + //Remove the marker and reference + this.currentObjects[signalId].remove(); + delete this.currentObjects[signalId]; + } + + return; + } + + if (this.currentObjects[signalId]){ + //marker exists + let marker = this.currentObjects[signalId]; + marker.setLatLng([signal.pos.z, signal.pos.x]); + marker.setPopupContent(this.createPopup(signal)); + + } else { + //marker does not exist + let marker = this.createMarker(signal); + marker.addTo(this); + + this.currentObjects[signalId] = marker; + } + }); + + Object.keys(this.currentObjects).forEach(existingId => { + var signalIsActive = this.signals.find((t) => { + var hash = this.hashPos(t.pos.x, t.pos.y, t.pos.z); + return hash == existingId; + }); + + if (!signalIsActive){ + this.currentObjects[existingId].remove(); + delete this.currentObjects[existingId]; + } + }); + }, + + reDraw: function(){ + this.currentObjects = {}; + this.clearLayers(); + + if (this.map.getZoom() < this.getMaxDisplayedZoom()) { + return; + } + + var mapLayer = this.layerMgr.getCurrentLayer(); + + this.signals.forEach(signal => { + if (!this.isSignalInCurrentLayer(signal)){ + //not in current layer + return; + } + + var marker = this.createMarker(signal); + marker.addTo(this); + var hash = this.hashPos(signal.pos.x, signal.pos.y, signal.pos.z); + this.currentObjects[hash] = marker; + }); + + }, + + onAdd: function(map) { + this.map = map; + this.layerMgr.addListener(() => this.reDraw()); + this.wsChannel.addListener("minetest-info", () => this.onMinetestUpdate()); + this.reDraw(); + }, + + onRemove: function(/*map*/) { + this.clearLayers(); + this.layerMgr.removeListener(() => this.reDraw()); + this.wsChannel.removeListener("minetest-info", () => this.onMinetestUpdate()); + } +});