dceejay / RedMap

A web map app for Node-RED to put blobs on
Apache License 2.0
110 stars 60 forks source link

Making RedMap usable beyond NodeRed #279

Open mhaberler opened 3 months ago

mhaberler commented 3 months ago

@dceejay here is a whacky idea

I like RedMap a lot, have used it in the past and find the idea of a mesage-driven map very compelling - it was super productive for my purpose and really left no urgent feature wishes for me

It would be wonderful to reuse RedMap in a non-NodeRed context, for instance in a PWA done with React, Vue or Svelte

why? because that wouldnt assume a Linux carriership is available - for instance an isolated application where sensor values come say via MQTT from embedded device and net connectivity cannot be assumed

I think the changes would be relativily minor to enable reuse of the RedMap - basically splitting out the SockJS connector into a separate file, and wrapping the core into some non-NodeRed examples which acquire the message context accordingly to the framework

I could imagine going for this work but I do not want to long-term fork RedMap for that

would you be willing to adopt such a split eventually, and occasionally give advice on the effort ?

of course assuming it doesnt bring down the house ;)

best regards Michael

ps: here's a use case example

dceejay commented 3 months ago

Hi, I'd like to understand some more how you think it would work. How could it be implemented without breaking the default Node-RED install ? What sort of devices are you thinking of serving it from ? There is quite a lot to host and serve (especially if you need to include maps). Given Node-RED runs on pretty small Linux devices like a PI zero and can also handle the data transformation part of your requirement there may not be much benefit... but I'm willing to be convinced.

mhaberler commented 3 months ago

what I am thinking of is a "map interpreter as an npm package" (lets call it RedMap Interpreter or RMI) which reacts to messages passed via a generic message IO channel. RMI would attach to an existing Leaflet instance passed at init time, or create its own if told.

the RedMap NodeRed extension would:

Other than the code base splitup there would be no semantic change to behavior. However now you can import the RMI package into an arbitrary web application and tie it to an arbitrary message context - since it's just about passing JSON back and forth

To explain how I arrived at that idea: I build a Node-Red/Redmap based flight display for hot air ballooning. Here it is:

image

The carrier ship: a mini PC runing Linux+NodeRED: image

It does all sorts of advanced stuff - read BLE sensors, receive and display ADS-B messages via RTL-SDR, vertical and ground speed, heading, sector range rings with dead reckoning to predict where you are going. It turned out to be super useful, for instance sector range rings with dead reckoning to predict where you are going.

And it was by any measure the clunkiest flight instrument I ever had - mostly because running NodeRed on Android doesnt hunt and lots of baggage is needed.

Applying 80/20, I can do most of the functionality with a Vue, React or Svelte PWA. And for that I'd want to keep RedMap - without the server entourage; no point in re-inventing that wheel. If I want to go further, I could move the PWA to React Native and use say the phone's BLE API. But for the standard case the location API as available in the browser is good enough. So here the "message context" is just updates from the browser AP's to location, barometer etc.

let me give another example:

https://windy.com is a popular weather app and based on Leaflet. Part of its appeal comes from its plugin capability (https://docs.windy-plugins.com/) which fostered enormous user creativity - among them all sorts of race trackers, like for yachting, planes etc. The scheme is identical: the plugin connects to some message source, and acts upon updates received - typically secure Websockets, MQTT-over-wss or Server Events.

Here's one of them - a boat tracker extension:

image

For every such plugin, folks have reinvented the wheel: adding icons, orienting and styling them, tracks etc - at which point I recommended to split the problem into a generic mapping part and a message adaptation layer - the latter could just be an edit field with an arrow function to transform whatever comes down the messaging channel at hand into something RedMap understands (for a related example see myhelloiot - the visual is created by editng a JSX fragment and includes the message transform)

third example: you have an event source which talks WSS or MQTT-WSS - but it's an embedded controller, not a linux box. A PWA does the job, and there's no point for a Linux box. I have good experience with PicoMQTT and work is underway to make that work over WSS.

I hope this gets the idea across: separate Leaflet handling from message context, thus making the map component reusable

I will try to do a PoC with a React Leaflet app using the sensor/location API in the browser, and butcher worldmap.js into place without regard for reusability, just to see if the idea flies.

dceejay commented 3 months ago

Hi, very cool application.

I sort of get it - but still struggling to see where you actually want the split to be - as I have many Leaflet plugins already included - are you trying to get below that so you can add other plugins - Ie just exposing the Leaflet layer as you say - or do you mean right at the top at the web socket level ? in which case just take the whole worldmap/worldmap directory as that is all the client side code, and you just need to replicate the server side parts to convert whatever into worldmap json objects over the socket.

Or is it to add something somewhere in between so that the client side has access to local sensors etc ? eg the current tracking button image that uses the location api

mhaberler commented 3 months ago

My assumption so far was:

but maybe this is a step to far ahead

probably a more immediate question is: can you envisage running RedMap referring to an existing Leaflet instance instead of creating its own?

dceejay commented 3 months ago

So you want both ? as at the top you want "arbitrary methods" and yet want an existing underlying instance of Leaflet.

All the plugins I add would also have to extend that instance ? What version of Leaflet would that be etc - I note Windy use a "slightly patched" version 1.4 - whereas I'm using 1.9 currently - so would all the plugins I use play nice ? Also in the general case how can we ensure compatibility ?

I guess you could check for the existence of the L. object and if it doesn't already exist then optionally load the leaflet library - but not sure how to do that as it's currently just a script include in the index.html - but happy to let you try.

mhaberler commented 3 months ago

with "arbitrary methods" I meant - messages directed to RedMap are not limited to the current SockWS code; they'd be passed to via a method from using code regardeless of ingress

yes, the plugin idea assumes an existing leaflet instance; good point about the versioning/compatibility issues

yes, the idea was to check at runtime if possible

I think the best bet is to attempt the butchering port and asess the fallout

too early to decide on feasibility