Move to sock.js, remove non-working overlays.

This commit is contained in:
Dave Conway-Jones 2017-08-13 18:31:53 +01:00
parent 63a35dd34c
commit c0c422075f
No known key found for this signature in database
GPG Key ID: 81B04231572A9A2D
7 changed files with 146 additions and 137 deletions

View File

@ -7,6 +7,7 @@ map web page for plotting "things" on.
![Map Image](https://dceejay.github.io/pages/images/redmap.png)
### Changes
- v1.1.0 - Move to sockjs (smaller than socket.io). Remove layers that are no longer served for free, Issue #24. Remove polygons as well as markers on timeout.
- v1.0.35 - Try to better center fa-icon and remove black square (Windows) - Issue #25
- v1.0.34 - Fix for icon not specified
- v1.0.33 - Add fa-icon without marker
@ -79,7 +80,7 @@ There are also several special icons...
- **hostile** : pseudo Nato style red circle.
- **neutral** : pseudo Nato style green square.
- **unknown** : pseudo Nato style yellow square.
- **earthquake** : black circle - diameter proportional to magnitude.
- **earthquake** : black circle - diameter proportional to `magnitude`.
#### Areas and Lines

View File

@ -1,10 +1,10 @@
{
"name" : "node-red-contrib-web-worldmap",
"version" : "1.0.35",
"version" : "1.1.0",
"description" : "A Node-RED node to provide a web page of a world map for plotting things on.",
"dependencies" : {
"express": "^4.15.0",
"socket.io": "^1.7.4",
"sockjs": "^0.3.18",
"cgi": "0.3.1"
},
"repository" : {

View File

@ -18,14 +18,15 @@ module.exports = function(RED) {
"use strict";
var path = require("path");
var express = require("express");
var io = require('socket.io');
var sockjs = require('sockjs');
var socket;
var WorldMap = function(n) {
RED.nodes.createNode(this,n);
if (!socket) {
var fullPath = path.posix.join(RED.settings.httpNodeRoot, 'worldmap', 'socket.io');
socket = io.listen(RED.server, {path:fullPath});
var fullPath = path.posix.join(RED.settings.httpNodeRoot, 'worldmap', 'leaflet', 'sockjs.min.js');
socket = sockjs.createServer({sockjs_url:fullPath, log:function() {}, transports:"xhr-polling"});
socket.installHandlers(RED.server, {prefix:'/worldmap/socket'});
}
this.lat = n.lat || "";
this.lon = n.lon || "";
@ -36,20 +37,19 @@ module.exports = function(RED) {
this.showmenu = n.usermenu || "show";
this.panit = n.panit || "false";
var node = this;
var clients = {};
//node.log("Serving map from "+__dirname+" as "+RED.settings.httpNodeRoot.slice(0,-1)+"/worldmap");
RED.httpNode.use("/worldmap", express.static(__dirname + '/worldmap'));
// add the cgi module for serving local maps....
RED.httpNode.use("/cgi-bin/mapserv", require('cgi')(__dirname + '/mapserv'));
var callback = function(client) {
client.setMaxListeners(0);
node.status({fill:"green",shape:"dot",text:"connected "+socket.engine.clientsCount});
function handler(msg) {
client.emit("worldmapdata",msg.payload);
}
node.on('input', handler);
client.on('worldmap', function(data) {
if (data.action === "connected") {
//client.setMaxListeners(0);
clients[client.id] = client;
node.status({fill:"green",shape:"dot",text:"connected "+Object.keys(clients).length});
client.on('data', function(message) {
message = JSON.parse(message);
if (message.action === "connected") {
var c = {init:true};
if (node.lat && node.lat.length > 0) { c.lat = node.lat; }
if (node.lon && node.lon.length > 0) { c.lon = node.lon; }
@ -59,23 +59,29 @@ module.exports = function(RED) {
if (node.maxage && node.maxage.length > 0) { c.maxage = node.maxage; }
c.showmenu = node.showmenu;
c.panit = node.panit;
client.emit("worldmapdata",{command:c});
client.write(JSON.stringify({command:c}));
}
});
client.on('disconnect', function() {
node.removeListener("input", handler);
node.status({fill:"green",shape:"ring",text:"connected "+socket.engine.clientsCount});
});
node.on("close", function() {
node.status({});
client.disconnect(true);
client.on('close', function() {
delete clients[client.id];
node.status({fill:"green",shape:"ring",text:"connected "+Object.keys(clients).length});
});
}
node.on("close", function() {
// socket.close();
// socket = null;
node.on('input', function(msg) {
for (var c in clients) {
if (clients.hasOwnProperty(c)) {
clients[c].write(JSON.stringify(msg.payload));
}
}
});
node.on("close", function() {
for (var c in clients) {
if (clients.hasOwnProperty(c)) {
clients[c].end();
}
}
node.status({});
});
node.status({});
socket.on('connection', callback);
}
RED.nodes.registerType("worldmap",WorldMap);
@ -84,60 +90,66 @@ module.exports = function(RED) {
var WorldMapIn = function(n) {
RED.nodes.createNode(this,n);
if (!socket) {
var fullPath = path.posix.join(RED.settings.httpNodeRoot, 'worldmap', 'socket.io');
socket = io.listen(RED.server, {path:fullPath});
var fullPath = path.posix.join(RED.settings.httpNodeRoot, 'worldmap', 'leaflet', 'sockjs.min.js');
socket = sockjs.createServer({sockjs_url:fullPath, prefix:'/worldmap/socket'});
socket.installHandlers(RED.server);
}
var node = this;
var clients = {};
var callback = function(client) {
client.setMaxListeners(0);
node.status({fill:"green",shape:"dot",text:"connected "+socket.engine.clientsCount});
client.on('worldmap', function(data) {
node.send({payload:data, topic:"worldmap"});
//client.setMaxListeners(0);
clients[client.id] = client;
node.status({fill:"green",shape:"dot",text:"connected "+Object.keys(clients).length});
client.on('data', function(message) {
message = JSON.parse(message);
node.send({payload:message, topic:"worldmap"});
});
client.on('disconnect', function() {
node.status({fill:"green",shape:"ring",text:"connected "+socket.engine.clientsCount});
node.send({payload:{action:"disconnect", clients:socket.engine.clientsCount}, topic:"worldmap"});
});
node.on("close", function() {
client.disconnect(true);
client.on('close', function() {
delete clients[client.id];
node.status({fill:"green",shape:"ring",text:"connected "+Object.keys(clients).length});
node.send({payload:{action:"disconnect", clients:Object.keys(clients).length}, topic:"worldmap"});
});
}
node.on("close", function() {
for (var c in clients) {
if (clients.hasOwnProperty(c)) {
clients[c].end();
}
}
node.status({});
//socket.close();
});
socket.on('connection', callback);
}
RED.nodes.registerType("worldmap in",WorldMapIn);
var satarray = {};
var WorldMapTracks = function(n) {
RED.nodes.createNode(this,n);
this.depth = Number(n.depth) || 20;
this.pointsarray = {};
var node = this;
node.on("input", function(msg) {
if (msg.hasOwnProperty("payload") && msg.payload.hasOwnProperty("name")) {
var newmsg = RED.util.cloneMessage(msg);
if (msg.payload.deleted) {
delete satarray[msg.payload.name];
delete node.pointsarray[msg.payload.name];
newmsg.payload.name = msg.payload.name + "_";
node.send(newmsg); // send the track to be deleted
return;
}
if (!satarray.hasOwnProperty(msg.payload.name)) {
satarray[msg.payload.name] = [];
if (!node.pointsarray.hasOwnProperty(msg.payload.name)) {
node.pointsarray[msg.payload.name] = [];
}
satarray[msg.payload.name].push(msg.payload);
if (satarray[msg.payload.name].length > node.depth) {
satarray[msg.payload.name].shift();
node.pointsarray[msg.payload.name].push(msg.payload);
if (node.pointsarray[msg.payload.name].length > node.depth) {
node.pointsarray[msg.payload.name].shift();
}
var line = [];
for (var i=0; i<satarray[msg.payload.name].length; i++) {
var m = satarray[msg.payload.name][i];
for (var i=0; i<node.pointsarray[msg.payload.name].length; i++) {
var m = node.pointsarray[msg.payload.name][i];
if (m.hasOwnProperty("lat") && m.hasOwnProperty("lon")) {
line.push( [m.lat*1, m.lon*1] );
delete newmsg.payload.lat;
@ -162,7 +174,7 @@ module.exports = function(RED) {
});
node.on("close", function() {
satarray = {};
node.pointsarray = {};
});
}
RED.nodes.registerType("worldmap-tracks",WorldMapTracks);

View File

@ -33,7 +33,7 @@
<link rel="shortcut icon" type="image/ico" href="favicon.ico"/>
<script type="text/javascript" src="leaflet/socket.io-1.4.5.js"></script>
<script type="text/javascript" src="leaflet/sockjs.min.js"></script>
<script type="text/javascript" src="leaflet/leaflet.js"></script>
<script type="text/javascript" src="leaflet/Leaflet.vector-markers.min.js"></script>
<script type="text/javascript" src="leaflet/leaflet.boatmarker.js"></script>
@ -58,7 +58,7 @@
<link rel="stylesheet" type="text/css" href="leaflet/dialog-polyfill.css"/>
</head>
<body onunload="ws.emit('end');">
<body onunload="ws.send(JSON.stringify({'action':'end'}));">
<div id="topbar">
<a href="http://nodered.org"><img src="images/node-red.png" width="60px" height="24px"/></a>
<span class="topbar"> Node-RED - map all the things</span>
@ -122,49 +122,45 @@ var ibmfoot = "&nbsp;&copy; IBM 2015,2017"
var initialposition = false;
var inIframe = false;
var showUserMenu = true;
var ws;
// Create the socket
var ws = io({path:location.pathname + 'socket.io'});
ws.on('connect', function() {
console.log("CONNECTED");
if (!inIframe) {
document.getElementById("foot").innerHTML = "<font color='#494'>"+ibmfoot+"</font>";
}
ws.emit("worldmap",{action:"connected"});
});
ws.on('disconnect', function() {
console.log("DISCONNECTED");
if (!inIframe) {
document.getElementById("foot").innerHTML = "<font color='#900'>"+ibmfoot+"</font>";
}
setTimeout(function() { ws.connect(); }, 2500);
});
ws.on('error', function() {
console.log("ERROR");
if (!inIframe) {
document.getElementById("foot").innerHTML = "<font color='#C00'>"+ibmfoot+"</font>";
}
setTimeout(function() { ws.connect(); }, 2500);
});
ws.on('worldmapdata', function(data) {
if (Array.isArray(data)) {
//console.log("ARRAY");
for (var prop in data) {
if (data[prop].command) { doCommand(data[prop].command); delete data[prop].command; }
if (data[prop].hasOwnProperty("name")) { setMarker(data[prop]); }
else { console.log("SKIP",data[prop]); }
var connect = function() {
ws = new SockJS(location.pathname + 'socket');
ws.onopen = function() {
console.log("CONNECTED");
if (!inIframe) {
document.getElementById("foot").innerHTML = "<font color='#494'>"+ibmfoot+"</font>";
}
}
else {
if (data.command) { doCommand(data.command); delete data.command; }
if (data.hasOwnProperty("name")) { setMarker(data); }
else { console.log("SKIP",data); }
}
});
ws.send(JSON.stringify({action:"connected"}));
};
ws.onclose = function() {
console.log("DISCONNECTED");
if (!inIframe) {
document.getElementById("foot").innerHTML = "<font color='#900'>"+ibmfoot+"</font>";
}
setTimeout(function() { connect(); }, 2500);
};
ws.onmessage = function(e) {
var data = JSON.parse(e.data);
//console.log("DATA",data);
if (Array.isArray(data)) {
//console.log("ARRAY");
for (var prop in data) {
if (data[prop].command) { doCommand(data[prop].command); delete data[prop].command; }
if (data[prop].hasOwnProperty("name")) { setMarker(data[prop]); }
else { console.log("SKIP",data[prop]); }
}
}
else {
if (data.command) { doCommand(data.command); delete data.command; }
if (data.hasOwnProperty("name")) { setMarker(data); }
else { console.log("SKIP",data); }
}
};
}
console.log("CONNECT TO",location.pathname + 'socket');
connect();
if ( window.localStorage.hasOwnProperty("lastpos") ) {
initialposition = true;
@ -186,6 +182,8 @@ if ( window.localStorage.hasOwnProperty("maxage") ) {
// Create the Initial Map object.
map = new L.map('map').setView(startpos, startzoom);
var menuButton = L.easyButton( 'fa-bars fa-lg', function() { toggleMenu(); }, "Toggle menu", "topright").addTo(map);
// Move some bits around if in an iframe
if (window.self !== window.top) {
console.log("IN an iframe");
@ -200,9 +198,7 @@ if (window.self !== window.top) {
(document.getElementById("bars").style.display="none");
(document.getElementById("menu").style.right="8px");
(document.getElementById("menu").style.borderRadius="6px");
if (showUserMenu) {
var menuButton = L.easyButton( 'fa-bars fa-lg', function() { toggleMenu(); }, "Toggle menu", "topright").addTo(map);
}
if (showUserMenu) { menuButton.addTo(map); }
}
else {
console.log("NOT in an iframe")
@ -296,7 +292,7 @@ function doTidyUp() {
delete polygons[m];
}
if (typeof polygons[m+"_"] != "undefined") {
//layers[markers[m+"_"].lay].removeLayer(polygons[m+"_"]);
layers[polygons[m+"_"].lay].removeLayer(polygons[m+"_"]);
delete polygons[m+"_"];
}
delete markers[m];
@ -409,7 +405,7 @@ map.on('overlayadd', function(e) {
overlays["drawing"].bringToBack();
}
//else { console.log("layer add :",e.name); }
ws.emit("worldmap",{action:"addlayer", name:e.name});
ws.send(JSON.stringify({action:"addlayer", name:e.name}));
});
map.on('overlayremove', function(e) {
@ -425,13 +421,13 @@ map.on('overlayremove', function(e) {
map.removeControl(drawControl);
}
//else console.log("layer del :",e.name);
ws.emit("worldmap",{action:"dellayer", name:e.name});
ws.send(JSON.stringify({action:"dellayer", name:e.name}));
});
map.on('baselayerchange', function(e) {
//console.log("base layer now :",e.name);
baselayername = e.name;
ws.emit("worldmap",{action:"layer", name:e.name});
ws.send(JSON.stringify({action:"layer", name:e.name}));
});
function showMapCurrentZoom() {
@ -467,7 +463,7 @@ map.on('zoomend', function() {
});
//map.on('contextmenu', function(e) {
// ws.emit("worldmap",{action:"rightclick", lat:e.latlng.lat.toFixed(5), lon:e.latlng.lng.toFixed(5)});
// ws.send(JSON.stringify({action:"rightclick", lat:e.latlng.lat.toFixed(5), lon:e.latlng.lng.toFixed(5)}));
//});
var rightmenuMap = L.popup().setContent("<input type='text' id='rinput' onkeydown='if (event.keyCode == 13) addThing();' placeholder='name (,icon, layer)'/>");
@ -476,7 +472,7 @@ var rclk;
var addThing = function() {
var thing = document.getElementById('rinput').value;
console.log(thing);
ws.emit("worldmap",{action:"point", lat:rclk.lat.toFixed(5), lon:rclk.lng.toFixed(5), point:thing});
ws.send(JSON.stringify({action:"point", lat:rclk.lat.toFixed(5), lon:rclk.lng.toFixed(5), point:thing}));
map.closePopup();
var bits = thing.split(",");
var lay = (bits[2] || "drawing").trim();
@ -521,7 +517,7 @@ function onLocationFound(e) {
var lla = new L.LatLng(ya,xa);
L.polygon([ e.latlng, lla ], {color:"cyan", weight:3, opacity:0.8, clickable:false}).addTo(map);
}
ws.emit("worldmap",{action:"point", lat:e.latlng.lat.toFixed(5), lon:e.latlng.lng.toFixed(5), point:"self", bearing:e.heading, speed:(e.speed*3.6 || undefined)});
ws.send(JSON.stringify({action:"point", lat:e.latlng.lat.toFixed(5), lon:e.latlng.lng.toFixed(5), point:"self", bearing:e.heading, speed:(e.speed*3.6 || undefined)}));
}
function onLocationError(e) { console.log(e.message); }
map.on('locationfound', onLocationFound);
@ -657,32 +653,32 @@ map.on('draw:created', function (e) {
var layer = e.layer;
//console.log(type, layer._latlngs);
//console.log(JSON.stringify(layer.toGeoJSON()));
ws.emit("worldmap",{action:"draw",type:type, points:layer._latlngs});
ws.send(JSON.stringify({action:"draw",type:type, points:layer._latlngs}));
layers["drawing"].addLayer(layer);
});
// Add the roads overlay
overlays["roads"] = L.tileLayer('http://otile{s}.mqcdn.com/tiles/1.0.0/{type}/{z}/{x}/{y}.{ext}', {
type: 'hyb',
ext: 'png',
attribution: '<a href="http://www.mapquest.com/">MapQuest</a> &mdash; Map data &copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
subdomains: '1234',
opacity: 0.9
});
overlays["rain"] = L.tileLayer('http://{s}.tile.openweathermap.org/map/rain/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution: 'Map data &copy; <a href="http://openweathermap.org">OpenWeatherMap</a>',
opacity: 0.5
});
overlays["pressure"] = L.tileLayer('http://{s}.tile.openweathermap.org/map/pressure_cntr/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution: 'Map data &copy; <a href="http://openweathermap.org">OpenWeatherMap</a>',
opacity: 0.5
});
overlays["weather"] = L.OWM.current({interval:30, minZoom:8, appId:"9ae11d4f6f9bed61f32fc061f715cc71"});
// // Add the roads overlay
// overlays["roads"] = L.tileLayer('http://otile{s}.mqcdn.com/tiles/1.0.0/{type}/{z}/{x}/{y}.{ext}', {
// type: 'hyb',
// ext: 'png',
// attribution: '<a href="http://www.mapquest.com/">MapQuest</a> &mdash; Map data &copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
// subdomains: '1234',
// opacity: 0.9
// });
//
// overlays["rain"] = L.tileLayer('http://{s}.tile.openweathermap.org/map/rain/{z}/{x}/{y}.png', {
// maxZoom: 18,
// attribution: 'Map data &copy; <a href="http://openweathermap.org">OpenWeatherMap</a>',
// opacity: 0.5
// });
//
// overlays["pressure"] = L.tileLayer('http://{s}.tile.openweathermap.org/map/pressure_cntr/{z}/{x}/{y}.png', {
// maxZoom: 18,
// attribution: 'Map data &copy; <a href="http://openweathermap.org">OpenWeatherMap</a>',
// opacity: 0.5
// });
//
// overlays["weather"] = L.OWM.current({interval:30, minZoom:8, appId:"9ae11d4f6f9bed61f32fc061f715cc71"});
overlays["buildings"] = new OSMBuildings(map).load();
map.removeLayer(overlays["buildings"]);
@ -712,11 +708,11 @@ var delMarker = function(dname) {
//console.log("Deleting",dname);
if (typeof polygons[dname] != "undefined") {
layers[polygons[dname].lay].removeLayer(polygons[dname]);
ws.emit("worldmap",{action:"delete", name:dname});
ws.send(JSON.stringify({action:"delete", name:dname}));
delete polygons[dname];
}
if (typeof markers[dname] != "undefined") {
ws.emit("worldmap",{action:"delete", name:dname});
ws.send(JSON.stringify({action:"delete", name:dname}));
layers[markers[dname].lay].removeLayer(markers[dname]);
delete markers[dname];
}
@ -768,14 +764,14 @@ function setMarker(data) {
if (opt.clickable) { polyln.bindPopup(data.name); }
polygons[data.name] = polyln;
polygons[data.name].lay = lay;
layers[lay].addLayer(polyln);
layers[lay].addLayer(polygons[data.name]);
}
else if (data.hasOwnProperty("area") && Array.isArray(data.area)) {
var polyarea = L.polygon(data.area, opt);
if (opt.clickable) { polyarea.bindPopup(data.name); }
polygons[data.name] = polyarea;
polygons[data.name].lay = lay;
layers[lay].addLayer(polyarea);
layers[lay].addLayer(polygons[data.name]);
}
else if (data.hasOwnProperty("sdlat") && data.hasOwnProperty("sdlon")) {
if (!data.hasOwnProperty("iconColor")) { opt.color = "blue"; } //different standard Color Settings
@ -1156,9 +1152,9 @@ function doCommand(cmd) {
if (cmd.hasOwnProperty("lon")) { clon = cmd.lon; }
if (cmd.hasOwnProperty("zoom")) { czoom = cmd.zoom; }
if (cmd.hasOwnProperty("cluster")) {
clusterAt = cmd.cluster;
// document.getElementById("setclus").value = cmd.cluster;
// setCluster();
//clusterAt = cmd.cluster;
document.getElementById("setclus").value = cmd.cluster;
setCluster();
}
if (cmd.hasOwnProperty("maxage")) {
document.getElementById("maxage").value = cmd.maxage;

File diff suppressed because one or more lines are too long

4
worldmap/leaflet/sockjs.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
CACHE MANIFEST
# date: Aug 10th 2017 - v1.0.35
# date: Aug 13th 2017 - v1.1.0
CACHE:
index.html
@ -40,7 +40,7 @@ leaflet/leaflet.measurecontrol.css
leaflet/leaflet.measurecontrol.js
leaflet/leaflet.select-layers.min.js
leaflet/OSMBuildings-Leaflet.js
leaflet/socket.io-1.4.5.js
leaflet/sockjs.min.js
leaflet/tile.stamen.js
leaflet/images/layers-2x.png
leaflet/images/layers.png