Can I use the worldmap plugin in node-red to view a building in 3D?

Hello.

I am trying to use the "worldmap" plugin in node-red to display a 3D building in Barcelona, Spain that I've constructed from polygons using coordinates from the following source (which also shows what the building is supposed to look like): 3D Tower made with Leaflet and OSMbuildings - bl.ocks.org

The problem is that I can only see it in 2D, as in the following screenshot: https://i.stack.imgur.com/Kftv0.png

The documentation for the worldmap plugin does say something about index3d.html, but when I browse to /worldmap/index3d.html instead of /worldmap/index.html, I get a completely blank page, with no map at all.

I confirmed that this is NOT due to a typo, because if I intentionally insert a typo, I get an error message. Per the documentation, I also tried using my own API key (per the documentation), but that didn't help.

Has anybody ever gotten a building to render in 3D, and if so, would you mind sharing your code and/or how you got index3d.html to not be a blank page?

node-red code is below:

[
    {
        "id": "21ba508dc4c4653a",
        "type": "tab",
        "label": "Auto-Update_bc",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "00d83d478ca0a1fc",
        "type": "inject",
        "z": "21ba508dc4c4653a",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "topic": "",
        "payloadType": "date",
        "x": 130,
        "y": 200,
        "wires": [
            [
                "833bc73b50bcca41"
            ]
        ]
    },
    {
        "id": "5a880b81067dacf2",
        "type": "function",
        "z": "21ba508dc4c4653a",
        "name": "Set Initial conditions",
        "func": "\nicons = [\"car\", \"ship\", \"bus\", \"plane\", \"iss\", \"uav\", \"friend\"];\nmsg.payload = {\"name\":\"test\", \"lat\":0.0, \"lon\":0.0,\"icon\":icons[Math.floor(Math.random()*icons.length)]};\nmsg.timestep = 0;\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 620,
        "y": 200,
        "wires": [
            [
                "33c3faef8e85ea91"
            ]
        ]
    },
    {
        "id": "9f2cc79939761256",
        "type": "worldmap",
        "z": "21ba508dc4c4653a",
        "name": "",
        "lat": "",
        "lon": "",
        "zoom": "",
        "layer": "OSMG",
        "cluster": "",
        "maxage": "",
        "usermenu": "show",
        "layers": "show",
        "panit": "false",
        "panlock": "false",
        "zoomlock": "false",
        "hiderightclick": "false",
        "coords": "none",
        "showgrid": "false",
        "allowFileDrop": "false",
        "path": "/worldmap",
        "overlist": "DR,CO,RA,DN,HM",
        "maplist": "OSMG,OSMC,EsriC,EsriS,EsriT,EsriDG,UKOS,SW",
        "mapname": "",
        "mapurl": "",
        "mapopt": "",
        "mapwms": false,
        "x": 1100,
        "y": 200,
        "wires": []
    },
    {
        "id": "33c3faef8e85ea91",
        "type": "function",
        "z": "21ba508dc4c4653a",
        "name": "Move Object",
        "func": "if (global.instruction == \"BREAK\") {\n    msg.payload.thing = \"Done\";\n    throw \"I'm Done\";\n}\n\n/*\nicons = [\"car\", \"ship\", \"bus\", \"plane\", \"iss\", \"uav\", \"friend\"];\nmsg.payload.icon = icons[Math.floor(Math.random()*icons.length)];\nmsg.payload.name = \"test\" + msg.timestep;\nmsg.timestep = msg.timestep + 1;\nmsg.payload.lon = msg.payload.lon +  1;\nmsg.payload.lon = msg.payload.lon % 180;\n*/\n\nvar geo = { \"type\": \"FeatureCollection\",\n\"features\": [\n          {\n            \"type\": \"Feature\",\n            \"properties\": {\n              \"wallColor\": \"rgb(255,0,0)\",\n              \"roofColor\": \"rgb(255,128,0)\",\n              \"height\": 30,\n              \"minHeight\": 0,\n              \"piso\": 0\n            },\n            \"geometry\": {\n              \"type\": \"Polygon\",\n              \"coordinates\": [\n                [\n                  [2.1853861212730408, 41.38901629106905],\n                  [2.185828685760498, 41.388623892423745],\n                  [2.1864724159240723, 41.38910281968238],\n                  [2.185984253883362, 41.3894167364756],\n                  [2.1853861212730408, 41.38901629106905]\n                ]\n              ]\n            }\n          },\n          {\n            \"type\": \"Feature\",\n            \"properties\": {\n              \"wallColor\": \"\",\n              \"roofColor\": \"\",\n              \"height\": 60,\n              \"minHeight\": 30,\n              \"piso\": 1\n            },\n            \"geometry\": {\n              \"type\": \"Polygon\",\n              \"coordinates\": [\n                [\n                  [2.185606062412262, 41.389012266479575],\n                  [2.1858233213424683, 41.3888210981928],\n                  [2.186225652694702, 41.38910483197434],\n                  [2.1859654784202576, 41.38927386427688],\n                  [2.185606062412262, 41.389012266479575]\n                ]\n              ]\n            }\n          },\n          {\n            \"type\": \"Feature\",\n            \"properties\": {\n              \"wallColor\": \"\",\n              \"roofColor\": \"\",\n              \"height\": 90,\n              \"minHeight\": 60,\n              \"piso\": 2\n            },\n            \"geometry\": {\n              \"type\": \"Polygon\",\n              \"coordinates\": [\n                [\n                  [2.185753583908081, 41.38902031565826],\n                  [2.1858367323875423, 41.388959946793776],\n                  [2.1860405802726746, 41.38910885655806],\n                  [2.1859386563301086, 41.389177274443526],\n                  [2.1857374906539917, 41.389022327952766],\n                  [2.185753583908081, 41.38902031565826]\n                ]\n              ]\n            }\n          },\n          {\n            \"type\": \"Feature\",\n            \"properties\": {\n              \"wallColor\": \"rgb(255,0,0)\",\n              \"roofColor\": \"rgb(255,128,0)\",\n              \"height\": 120,\n              \"minHeight\": 90,\n              \"piso\": 3\n            },\n            \"geometry\": {\n              \"type\": \"Polygon\",\n              \"coordinates\": [\n                [\n                  [2.185858190059662, 41.38905653695002],\n                  [2.185858190059662, 41.38907867217396],\n                  [2.185882329940796, 41.38907867217396],\n                  [2.185882329940796, 41.38905653695002],\n                  [2.185858190059662, 41.38905653695002]\n                ]\n              ]\n            }\n          }\n]\n}\n\nmsg.payload.command = {map:{overlay:\"Building \" + msg.timestep.toString(), geojson:geo, fit:false}};\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 850,
        "y": 200,
        "wires": [
            [
                "73887a06a6c29e1f",
                "9f2cc79939761256"
            ]
        ]
    },
    {
        "id": "833bc73b50bcca41",
        "type": "change",
        "z": "21ba508dc4c4653a",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "instruction",
                "pt": "global",
                "to": "GO",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 360,
        "y": 200,
        "wires": [
            [
                "5a880b81067dacf2"
            ]
        ]
    },
    {
        "id": "d2eb2693c01b45b5",
        "type": "switch",
        "z": "21ba508dc4c4653a",
        "name": "",
        "property": "instruction",
        "propertyType": "global",
        "rules": [
            {
                "t": "neq",
                "v": "STOP",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 910,
        "y": 280,
        "wires": [
            [
                "33c3faef8e85ea91"
            ]
        ]
    },
    {
        "id": "73887a06a6c29e1f",
        "type": "delay",
        "z": "21ba508dc4c4653a",
        "name": "",
        "pauseType": "delay",
        "timeout": "5",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "allowrate": false,
        "outputs": 1,
        "x": 780,
        "y": 280,
        "wires": [
            [
                "d2eb2693c01b45b5"
            ]
        ]
    },
    {
        "id": "b5cf5eebe2c484d5",
        "type": "inject",
        "z": "21ba508dc4c4653a",
        "name": "Breaker",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payloadType": "date",
        "x": 150,
        "y": 380,
        "wires": [
            [
                "1bccee288132318f"
            ]
        ]
    },
    {
        "id": "1bccee288132318f",
        "type": "change",
        "z": "21ba508dc4c4653a",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "instruction",
                "pt": "global",
                "to": "STOP",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 370,
        "y": 380,
        "wires": [
            []
        ]
    }
]

I think I may have figured out the issue. I re-generated the API key, this time without checking any of the additional check boxes. This fixed the problem of index3d.html rendering as a blank page.

1 Like

Yes sadly osmbuildings seemed to have stopped/blocked/removed access to a simple version of the style file necessary to render these without a key - so you must now have your own mapboxgl api token.

As this is now the case I will look to see if there is a simpler way to set this up without adding yet another input to the config node. Maybe via an environment variable. I'll also make the page warn/alert so the user knows what to do.