Map Widget

Usage: modify the urls according to your systems and provide your Google Map API key.

This flow adds a map widget to Node-RED Dasboard nodes.

It employs a web template node and a ui_template dashboard node.

The web template node serves a map interface, which is then embedded into the ui_template node.

Inter-frames communication allows messages injected to ui_template node to be sent to the web template node, which eventually displays injected data to the map interface.

Final result looks like this:

https://snag.gy/KL8HGu.jpg

[
    {
        "id": "7d033e9a.d1131",
        "type": "ui_template",
        "z": "4499b290.3eec5c",
        "group": "88f77589.0122d8",
        "name": "Map widget",
        "order": 0,
        "width": "24",
        "height": "14",
        "format": "<iframe \n    id='frame'\n    src='.../mapui'\n    width='100%'  \n    height='100%'\n>\n</iframe>\n\n<script>\nscope.$watch('msg.payload', function(newv, oldv, scope) {\n    $(\"#frame\")[0].contentWindow.postMessage(JSON.stringify(newv), '*');\n});\n</script>",
        "storeOutMessages": false,
        "fwdInMessages": false,
        "x": 724,
        "y": 1698,
        "wires": [
            []
        ]
    },
    {
        "id": "c433a1b9.252a8",
        "type": "http response",
        "z": "4499b290.3eec5c",
        "name": "",
        "x": 748,
        "y": 1749,
        "wires": []
    },
    {
        "id": "aa254267.9215f",
        "type": "http in",
        "z": "4499b290.3eec5c",
        "name": "",
        "url": ".../mapui",
        "method": "get",
        "swaggerDoc": "",
        "x": 384,
        "y": 1749,
        "wires": [
            [
                "7b50d31e.26176c"
            ]
        ]
    },
    {
        "id": "7b50d31e.26176c",
        "type": "template",
        "z": "4499b290.3eec5c",
        "name": "Map UI",
        "field": "payload",
        "fieldType": "msg",
        "syntax": "mustache",
        "template": "<!DOCTYPE html>\n<html>\n<head>\n  <title>Vancouver Buses</title>\n  <script src=\"https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js\"></script>\n  <script src=\"https://maps.googleapis.com/maps/api/js?key=<GOOGLE_MAP_KEY_HERE>\"></script>\n  <script src=\"https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/markerclusterer.js\"></script>\n\n  <style type=\"text/css\" media=\"screen\">\n    #map {\n      position:absolute;\n      top: 0; bottom: 0; left: 0; right: 0;\n    }\n  </style>\n</head>\n<body>\n  <div id=\"map\"></div>\n  <script type=\"text/javascript\">\n\n$(document).ready(function(){\n  var MAP_ZOOM = 12\n  var MARKER_SIZE = 14\n  \n  var map = new google.maps.Map(document.getElementById('map'), {\n      zoom: MAP_ZOOM,\n      center: {lat: 49.269801, lng: -123.109489}\n    });\n    \n  var markers = []\n  \n  window.onmessage = function(evt){\n    for (var i = 0; i < markers.length; i++) {\n      markers[i].setMap(null);\n    }\n    \n    var data = JSON.parse(evt.data);\n    map.setZoom(MAP_ZOOM);\n    \n    markers = data.map(function(el, i) {\n      var marker = new google.maps.Marker({\n        position: el,\n        icon: {\n          url: el.iconUrl,\n          scaledSize: new google.maps.Size(MARKER_SIZE, MARKER_SIZE)\n        },\n        map:map\n      });\n      google.maps.event.addListener(marker , 'click', function(){\n        var infowindow = new google.maps.InfoWindow({\n          content:el.description,\n          position: el,\n        });\n        infowindow.open(map);\n        setTimeout(function () { infowindow.close(); }, 2000);\n      });\n      return marker\n    });\n  }\n});\n  </script>\n</body>\n</html>",
        "x": 586,
        "y": 1749,
        "wires": [
            [
                "c433a1b9.252a8"
            ]
        ]
    },
    {
        "id": "d0c4c947.e3b1b8",
        "type": "comment",
        "z": "4499b290.3eec5c",
        "name": "Iframe embedded inside Map widget node",
        "info": "",
        "x": 444.5,
        "y": 1790,
        "wires": []
    },
    {
        "id": "f906d86d.fa7ac8",
        "type": "inject",
        "z": "4499b290.3eec5c",
        "name": "",
        "topic": "",
        "payload": "[{\"lat\":49.268311, \"lng\":-123.148146, \"description\":\"awefa\", \"iconUrl\":\"http://cdn.mysitemyway.com/etc-mysitemyway/icons/legacy-previews/icons-256/pink-jelly-icons-arrows/009173-pink-jelly-icon-arrows-triangle-solid-left.png\"},{\"lat\":49.265311, \"lng\":-123.148146, \"description\":\"awefa\", \"iconUrl\":\"http://cdn.mysitemyway.com/etc-mysitemyway/icons/legacy-previews/icons-256/pink-jelly-icons-arrows/009173-pink-jelly-icon-arrows-triangle-solid-left.png\"}]",
        "payloadType": "json",
        "repeat": "",
        "crontab": "",
        "once": false,
        "x": 531,
        "y": 1697,
        "wires": [
            [
                "7d033e9a.d1131"
            ]
        ]
    },
    {
        "id": "88f77589.0122d8",
        "type": "ui_group",
        "z": "",
        "name": "Test",
        "tab": "2b906797.81baa8",
        "disp": true,
        "width": "24"
    },
    {
        "id": "2b906797.81baa8",
        "type": "ui_tab",
        "z": "",
        "name": "Test2",
        "icon": "dashboard"
    }
]
namgk

Flow Info

created 2 months, 1 week ago

Node Types

Core
  • comment (x1)
  • http in (x1)
  • http response (x1)
  • inject (x1)
  • template (x1)
Other
  • ui_group (x1)
  • ui_tab (x1)
  • ui_template (x1)

Tags

  • map
  • markers
Copy this flow JSON to your clipboard and then import into Node-RED using the Import From > Clipboard (Ctrl-I) menu option