Add embedded example

This commit is contained in:
Dave Conway-Jones 2016-11-22 08:21:56 +00:00
parent e1cc6209bf
commit bf2aad4bf6
6 changed files with 250 additions and 43 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.0.22 - Add example how to embed into Node-RED-Dashboard template.
- v1.0.21 - If you specify range and icon then you get a marker and a range circle, if you just specify range with no icon, you just get a circle, and vice versa.
- v1.0.20 - Add buildings overlay.
- v1.0.19 - Add circle mode - specify name, lat, lon and radius.

View File

@ -0,0 +1,158 @@
[
{
"id": "104f9b89.5daf04",
"type": "worldmap",
"z": "5ab56e5e.449a5",
"name": "",
"lat": "",
"lon": "",
"zoom": "",
"layer": "OSM",
"cluster": "",
"maxage": "",
"usermenu": "hide",
"panit": "true",
"x": 490,
"y": 280,
"wires": []
},
{
"id": "7892d55a.40864c",
"type": "inject",
"z": "5ab56e5e.449a5",
"name": "",
"topic": "",
"payload": "",
"payloadType": "str",
"repeat": "",
"crontab": "",
"once": false,
"x": 130,
"y": 220,
"wires": [
[
"45dc04c5.811fcc"
]
]
},
{
"id": "45dc04c5.811fcc",
"type": "function",
"z": "5ab56e5e.449a5",
"name": "",
"func": "// create random position\nvar lat = 51 + Math.random() * 0.2;\nvar lon = -1.45 + Math.random() * 0.2;\nmsg.payload={lat:lat, lon:lon, name:\"Mike\", icon:\"male\", url:\"<a href=\\\"/red/ui/#/0\\\">IBM link</a>\"};\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 310,
"y": 280,
"wires": [
[
"104f9b89.5daf04"
]
]
},
{
"id": "39ae2a4d.5a6f06",
"type": "inject",
"z": "5ab56e5e.449a5",
"name": "",
"topic": "",
"payload": "/red/worldmap",
"payloadType": "str",
"repeat": "",
"crontab": "",
"once": true,
"x": 140,
"y": 340,
"wires": [
[
"a8660ccf.d7166"
]
]
},
{
"id": "be72c0ae.5925b",
"type": "ui_template",
"z": "5ab56e5e.449a5",
"group": "c60f4e05.ebb48",
"name": "",
"order": 0,
"width": "6",
"height": "6",
"format": "<div ng-bind-html=\"msg.payload | trusted\"></div>",
"storeOutMessages": true,
"fwdInMessages": true,
"x": 480,
"y": 340,
"wires": [
[]
]
},
{
"id": "a8660ccf.d7166",
"type": "template",
"z": "5ab56e5e.449a5",
"name": "",
"field": "payload",
"fieldType": "msg",
"format": "handlebars",
"syntax": "mustache",
"template": "<iframe src={{{payload}}} height=300px ></iframe>",
"x": 310,
"y": 340,
"wires": [
[
"be72c0ae.5925b"
]
]
},
{
"id": "79411e5e.1af57",
"type": "ui_button",
"z": "5ab56e5e.449a5",
"name": "",
"group": "c60f4e05.ebb48",
"order": 0,
"width": 0,
"height": 0,
"label": "Move Mike",
"color": "",
"icon": "fa-male",
"payload": "",
"payloadType": "str",
"topic": "",
"x": 130,
"y": 280,
"wires": [
[
"45dc04c5.811fcc"
]
]
},
{
"id": "235ad210.492b0e",
"type": "comment",
"z": "5ab56e5e.449a5",
"name": "How to embed Map in Dashboard",
"info": "This example shows how to embed the Worldmap \ninto a template node within the `node-red-dashboard`\n\nThe first flow creates a dashboard button that \ngenerates a randon position, with the required \nicon, and passes that to the worldmap. The\nmap is configured to automatically pan to the\nposition of any point that arrives.\n\nThe second flow initialise the dashboard template\nwith the initial map and sets it to a more square shape\nby adjusting the height.",
"x": 180,
"y": 160,
"wires": []
},
{
"id": "c60f4e05.ebb48",
"type": "ui_group",
"z": "5ab56e5e.449a5",
"name": "Default",
"tab": "6a3aec18.0bc474",
"disp": true,
"width": "6"
},
{
"id": "6a3aec18.0bc474",
"type": "ui_tab",
"z": "5ab56e5e.449a5",
"name": "Home",
"icon": "dashboard"
}
]

View File

@ -43,11 +43,22 @@
</div>
<div class="form-row">
<label for="node-input-cluster"><i class="fa fa-gears"></i> Cluster at</label>
zoom levels less than <input type="text" id="node-input-cluster" placeholder="10 (0-19)" style="width:60px;">
zoom levels less than <input type="text" id="node-input-cluster" placeholder="10 (0-19)" style="width:70px;">
</div>
<div class="form-row">
<label for="node-input-maxage"><i class="fa fa-timer"></i> Max age</label>
Remove markers after <input type="text" id="node-input-maxage" style="width:60px;"> seconds
<label for="node-input-maxage"><i class="fa fa-clock-o"></i> Max age</label>
Remove markers after <input type="text" id="node-input-maxage" style="width:67px;"> seconds
</div>
<div class="form-row">
<label for="node-input-usermenu"><i class="fa fa-user"></i> User Menu</label>
<select id="node-input-usermenu" style="width:70px;">
<option value="show">Show</option>
<option value="hide">Hide</option>
</select>
<i class="fa fa-arrows-alt" style="margin-left:50px"></i> Auto-pan <select id="node-input-panit" style="width:70px;">
<option value="false">False</option>
<option value="true">True</option>
</select>
</div>
<div class="form-row">
<label for="node-input-name"><i class="fa fa-file"></i> Name</label>
@ -84,13 +95,15 @@
category: 'location',
color:"darksalmon",
defaults: {
name: {value:""},
lat: {value:""},
lon: {value:""},
zoom: {value:""},
layer: {value:""},
cluster: {value:""},
maxage: {value:""},
name: {value:""}
usermenu: {value:"show"},
panit: {value:"false"}
},
inputs:1,
outputs:0,

View File

@ -29,6 +29,8 @@ module.exports = function(RED) {
this.layer = n.layer || "";
this.cluster = n.cluster || "";
this.maxage = n.maxage || "";
this.showmenu = n.usermenu || "show";
this.panit = n.panit || "false";
var node = this;
//node.log("Serving map from "+__dirname+" as "+RED.settings.httpNodeRoot.slice(0,-1)+"/worldmap");
RED.httpNode.use("/worldmap", express.static(__dirname + '/worldmap'));
@ -49,6 +51,8 @@ module.exports = function(RED) {
if (node.layer && node.layer.length > 0) { c.layer = node.layer; }
if (node.cluster && node.cluster.length > 0) { c.cluster = node.cluster; }
if (node.maxage && node.maxage.length > 0) { c.maxage = node.maxage; }
c.showmenu = node.showmenu;
c.panit = node.panit;
client.emit("worldmapdata",{command:c});
}
});
@ -57,14 +61,11 @@ module.exports = function(RED) {
node.status({fill:"green",shape:"ring",text:"connected "+socket.engine.clientsCount});
});
node.on("close", function() {
node.status({});
client.disconnect(true);
});
}
node.on("close", function() {
node.status({});
//socket.close();
});
node.status({});
socket.on('connection', callback);
}
RED.nodes.registerType("worldmap",WorldMap);

View File

@ -77,7 +77,7 @@
<tr><td style="cursor:default"><span id="showHelp" ><i class="fa fa-info fa-lg fa-fw"></i>Help</span></td></tr>
</table></div>
<div id="map"></div>
<div id="foot">&nbsp;&copy; IBM 2015,2016</div>
<div id="foot"></div>
<!-- <div id="heat"><button type="button" onclick="clearHeat();">Clear Heatmap</button></div> -->
<dialog id="helpWindow">
@ -120,25 +120,33 @@ var maxage = 600; // default max age of icons on map in seconds - cleared afte
var baselayername = "OSM grey"; // Default base layer OSM but uniform grey
var ibmfoot = "&nbsp;&copy; IBM 2015,2016"
var initialposition = false;
var inIframe = false;
var showUserMenu = true;
// Create the socket
var ws = io();
ws.on('connect', function() {
console.log("CONNECTED");
document.getElementById("foot").innerHTML = "<font color='#494'>"+ibmfoot+"</font>";
if (!inIframe) {
document.getElementById("foot").innerHTML = "<font color='#494'>"+ibmfoot+"</font>";
}
ws.emit("worldmap",{action:"connected"});
});
ws.on('disconnect', function() {
console.log("DISCONNECTED");
document.getElementById("foot").innerHTML = "<font color='#900'>"+ibmfoot+"</font>";
if (!inIframe) {
document.getElementById("foot").innerHTML = "<font color='#900'>"+ibmfoot+"</font>";
}
setTimeout(function() { ws.connect(); }, 2500);
});
ws.on('error', function() {
console.log("ERROR");
document.getElementById("foot").innerHTML = "<font color='#C00'>"+ibmfoot+"</font>";
if (!inIframe) {
document.getElementById("foot").innerHTML = "<font color='#C00'>"+ibmfoot+"</font>";
}
setTimeout(function() { ws.connect(); }, 2500);
});
@ -171,6 +179,7 @@ map = new L.map('map').setView(startpos, startzoom);
// Move some bits around if in an iframe
if (window.self !== window.top) {
console.log("IN an iframe");
inIframe = true;
(document.getElementById("topbar").style.display="none");
(document.getElementById("map").style.top="0px");
(document.getElementById("results").style.right="50px");
@ -181,36 +190,43 @@ if (window.self !== window.top) {
(document.getElementById("bars").style.display="none");
(document.getElementById("menu").style.right="8px");
(document.getElementById("menu").style.borderRadius="6px");
L.easyButton( 'fa-bars fa-lg', function() { toggleMenu(); }, "Toggle menu", "topright").addTo(map);
if (showUserMenu) {
var menuButton = L.easyButton( 'fa-bars fa-lg', function() { toggleMenu(); }, "Toggle menu", "topright").addTo(map);
}
}
else {
console.log("NOT in an iframe")
window.onbeforeunload = function(e) {
return 'Reloading will delete all the local markers, including any drawing on the "drawing" layer';
};
if (!showUserMenu) {
document.getElementById("bars").style.display="none";
}
}
// Add the fullscreen button
L.control.fullscreen().addTo(map);
if (!inIframe) {
// Add the fullscreen button
L.control.fullscreen().addTo(map);
// map.on('fullscreenchange', function () {
// if (map.isFullscreen()) { console.log('entered fullscreen') }
// else { console.log('exited fullscreen'); }
// });
// map.on('fullscreenchange', function () {
// if (map.isFullscreen()) { console.log('entered fullscreen') }
// else { console.log('exited fullscreen'); }
// });
// Add the locate my position button
L.easyButton( 'fa-crosshairs fa-lg', function() {
map.locate({setView:true, maxZoom:16});
}, "Locate me").addTo(map);
// Add the locate my position button
L.easyButton( 'fa-crosshairs fa-lg', function() {
map.locate({setView:true, maxZoom:16});
}, "Locate me").addTo(map);
// Add the measure/ruler button
L.Control.measureControl().addTo(map);
// Add the measure/ruler button
L.Control.measureControl().addTo(map);
// Create the clear heatmap button
var clrHeat = L.easyButton( '<b>Reset Heatmap</b>', function() {
console.log("reset heatmap");
heat.setLatLngs([]);
}, "Clears the current heatmap", "bottomright");
// Create the clear heatmap button
var clrHeat = L.easyButton( '<b>Reset Heatmap</b>', function() {
console.log("reset heatmap");
heat.setLatLngs([]);
}, "Clears the current heatmap", "bottomright");
}
// Handle the dialog for popup help
var dialog = document.querySelector('dialog');
@ -511,30 +527,30 @@ basemaps["OSM"] = osm;
// Extra Leaflet map layers from http://leaflet-extras.github.io/leaflet-providers/preview/
var Esri_WorldStreetMap = L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles &copy; Esri &mdash; Source: Esri, DeLorme, NAVTEQ, USGS, Intermap, iPC, NRCAN, Esri Japan, METI, Esri China (Hong Kong), Esri (Thailand), TomTom, 2012'
attribution: 'Tiles &copy; Esri'
});
basemaps["Esri"] = Esri_WorldStreetMap;
var Esri_WorldImagery = L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles &copy; Esri &mdash; Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
attribution: 'Tiles &copy; Esri'
});
basemaps["Esri Satellite"] = Esri_WorldImagery;
var Esri_WorldShadedRelief = L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles &copy; Esri &mdash; Source: Esri',
attribution: 'Tiles &copy; Esri',
maxNativeZoom: 13
});
basemaps["Esri Terrain"] = Esri_WorldShadedRelief;
var Esri_OceanBasemap = L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/Ocean_Basemap/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles &copy; Esri &mdash; Sources: GEBCO, NOAA, CHS, OSU, UNH, CSUMB, National Geographic, DeLorme, NAVTEQ, and Esri',
attribution: 'Tiles &copy; Esri',
maxNativeZoom: 10
});
basemaps["Esri Ocean"] = Esri_OceanBasemap;
var OpenMapSurfer_Roads = L.tileLayer('http://korona.geog.uni-heidelberg.de/tiles/roads/x={x}&y={y}&z={z}', {
maxZoom: 18,
attribution: 'Imagery from <a href="http://giscience.uni-hd.de/">GIScience Research Group @ University of Heidelberg</a> &mdash; Map data &copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
attribution: 'Imagery from <a href="http://giscience.uni-hd.de/">University of Heidelberg</a> &mdash; Map data &copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
});
basemaps["Mapsurfer"] = OpenMapSurfer_Roads;
@ -548,7 +564,7 @@ basemaps["Mapsurfer"] = OpenMapSurfer_Roads;
//basemaps["MapQuest OSM"] = MapQuestOpen_OSM;
var Esri_NatGeoWorldMap = L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles &copy; Esri &mdash; National Geographic, Esri, DeLorme, NAVTEQ, UNEP-WCMC, USGS, NASA, ESA, METI, NRCAN, GEBCO, NOAA, iPC',
attribution: 'Tiles &copy; Esri',
maxNativeZoom: 12
});
basemaps["Nat Geo"] = Esri_NatGeoWorldMap;
@ -563,7 +579,7 @@ var NLS_OS_opendata = L.tileLayer('http://geo.nls.uk/maps/opendata/{z}/{x}/{y}.p
basemaps["UK OS Opendata"] = NLS_OS_opendata;
var NLS_OS_1919_1947 = L.tileLayer( 'http://nls-{s}.tileserver.com/nls/{z}/{x}/{y}.jpg', {
attribution: 'Historical Maps Layer, 1919-1947 from the <a href="http://maps.nls.uk/projects/api/">NLS Maps API</a>',
attribution: 'Historical Maps Layer, from <a href="http://maps.nls.uk/projects/api/">NLS Maps</a>',
bounds: [[49.6, -12], [61.7, 3]],
minZoom: 1,
maxZoom: 18,
@ -635,7 +651,7 @@ map.on('draw:created', function (e) {
overlays["roads"] = L.tileLayer('http://otile{s}.mqcdn.com/tiles/1.0.0/{type}/{z}/{x}/{y}.{ext}', {
type: 'hyb',
ext: 'png',
attribution: 'Tiles Courtesy of <a href="http://www.mapquest.com/">MapQuest</a> &mdash; Map data &copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
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
});
@ -671,7 +687,9 @@ if ( window.localStorage.hasOwnProperty("lastlayer") ) {
basemaps[baselayername].addTo(map);
// Add the layers control widget
var layercontrol = L.control.layers(basemaps, overlays).addTo(map);
if (!inIframe) {
var layercontrol = L.control.layers(basemaps, overlays).addTo(map);
}
// Layer control based on select box rather than radio buttons.
//var layercontrol = L.control.selectLayers(basemaps, overlays).addTo(map);
@ -693,7 +711,7 @@ var delMarker = function(dname) {
// the MAIN add something to map function
function setMarker(data) {
//console.log(typeof data, data);
console.log(typeof data, data);
var ll;
var stay = popped;
@ -707,7 +725,9 @@ function setMarker(data) {
//zoomToBoundsOnClick:false
}).addTo(map);
overlays[lay] = layers[lay];
layercontrol.addOverlay(layers[lay],lay);
if (!inIframe) {
layercontrol.addOverlay(layers[lay],lay);
}
}
if (typeof markers[data.name] != "undefined") { layers[lay].removeLayer(markers[data.name]); }
@ -927,6 +947,20 @@ function doCommand(cmd) {
if (cmd.hasOwnProperty("init") && initialposition) {
return;
}
if (cmd.hasOwnProperty("panit")) {
if (cmd.panit === "true") { panit = true; }
else { panit = false; }
}
if (cmd.hasOwnProperty("showmenu")) {
if ((cmd.showmenu === "hide") && (showUserMenu === true)) {
showUserMenu = false;
map.removeControl(menuButton);
}
else if ((cmd.showmenu === "show") && (showUserMenu === false)) {
showUserMenu = true;
map.addControl(menuButton);
}
}
var existsalready = false;
// Add a new base map layer
if (cmd.map && cmd.map.hasOwnProperty("name") && cmd.map.hasOwnProperty("url") && cmd.map.hasOwnProperty("opt")) {

View File

@ -1,5 +1,5 @@
CACHE MANIFEST
# date: Nov 11th v1.0.21
# date: Nov 22nd v1.0.22
CACHE:
index.html