2018-06-01 05:50:50 +08:00
# node-red-contrib-web-worldmap
2019-11-03 02:03:43 +08:00
[![npm version ](https://badge.fury.io/js/node-red-contrib-web-worldmap.svg )](https://badge.fury.io/js/node-red-contrib-web-worldmap)
[![GitHub license ](https://github.com/dceejay/redmap/blob/master/LICENSE )](https://img.shields.io/github/license/dceejay/redmap.svg)
2019-03-04 16:45:56 +08:00
A < a href = "https://nodered.org" target = "mapinfo" > Node-RED< / a > node to provide a world
2016-04-01 18:31:07 +08:00
map web page for plotting "things" on.
2016-08-05 00:09:27 +08:00
![Map Image ](https://dceejay.github.io/pages/images/redmap.png )
2018-06-01 16:34:48 +08:00
### Updates
2018-10-25 16:56:42 +08:00
2019-10-16 18:26:00 +08:00
- v2.1.5 - Fix squawk icon color handling
2019-10-16 17:20:29 +08:00
- v2.1.4 - Fix alt and speed as strings
2019-09-27 19:21:59 +08:00
- v2.1.3 - Fix web page file path error
2019-09-18 22:38:03 +08:00
- v2.1.2 - Fix layercontrol remove bug. Issue #116
2019-09-17 04:35:06 +08:00
- v2.1.1 - fix bug in repeated add with polygon
- v2.1.0 - add ui-worldmap node to make embedding in Dashboard easier. Let -in node specify connection actions only.
2019-08-20 20:33:36 +08:00
- v2.0.22 - fix SIDC missing property
2019-09-02 22:08:34 +08:00
- v2.0.21 - allow adding overlays without making them visible (visible:false). Issue #108
2019-08-08 19:28:53 +08:00
- v2.0.20 - ensure `fit` option is boolean, Issue #109 . Fix track layers, Issue #110 .
2019-07-01 01:30:24 +08:00
- v2.0.18 - Stop map contextmenu bleedthrough to marker. Add compress middleware.
2019-06-21 06:13:24 +08:00
- v2.0.17 - Let clear command also clear tracks from tracks node
- v2.0.16 - Revert use of ES6 import. Keep IE11 happy for while
2019-06-14 23:43:20 +08:00
- v2.0.13 - Fix tracks colour.
2019-05-23 16:02:25 +08:00
- v2.0.12 - Ensure default icon is in place if not specified (regression)
2019-05-22 19:27:33 +08:00
- v2.0.9 - Only update maxage on screen once it exists
2019-05-08 23:36:52 +08:00
- v2.0.8 - Drop beta flag, re-organise index, js and css files. Now using leaflet 1.4
2019-05-07 01:19:26 +08:00
- v2.0.7-beta - Switch Ruler control to be independent of Draw library.
2019-05-01 19:31:58 +08:00
- v2.0.6-beta - Re-enable editing of draw layer, add rectangles to lines and areas. Make individual objects editable.
2019-04-27 16:18:24 +08:00
- v2.0.5-beta - Fix clustering on zoom (update old library)
2019-04-26 07:09:21 +08:00
- v2.0.4-beta - Add helicopter icon. Correct Leaflet.Coordinates file name. Fix right contextmenu.
2019-04-24 06:56:14 +08:00
- v2.0.3-beta - Let circles have popups. Better drawing of ellipses
2019-04-23 20:20:19 +08:00
- v2.0.2-beta - Let lines and areas also have popups
2019-04-22 05:32:01 +08:00
- v2.0.1-beta - Add optional graticule
2019-04-22 01:51:39 +08:00
- v2.0.0-beta - Move to leaflet 1.4.x plus all plugins updated
2018-11-17 20:10:46 +08:00
- ...
2018-06-01 16:34:48 +08:00
see [CHANGELOG ](https://github.com/dceejay/RedMap/blob/master/CHANGELOG.md ) for full list.
2018-05-18 16:59:46 +08:00
## Install
2018-06-01 16:34:48 +08:00
Either use the Manage Palette option in the Node-RED Editor menu, or run the following command in your Node-RED user directory - typically `~/.node-red`
2016-04-01 18:31:07 +08:00
2019-09-27 19:21:59 +08:00
npm i node-red-contrib-web-worldmap
2018-06-01 06:02:01 +08:00
2018-06-01 21:04:06 +08:00
## Usage
2016-04-01 18:31:07 +08:00
2019-02-17 01:40:28 +08:00
Plots "things" on a map. By default the map will be served from `{httpRoot}/worldmap` , but this
can be configured in the configuration panel.
2016-04-01 18:31:07 +08:00
2018-06-01 16:34:48 +08:00
Use keyboard shortcut `⌘⇧m` , `ctrl-shift-m` to jump to the map.
2019-03-04 16:45:56 +08:00
The minimum **msg.payload** must contain `name` , `lat` and `lon` properties, for example
2016-04-01 18:31:07 +08:00
2019-02-17 01:40:28 +08:00
msg.payload = { "name":"Jason", "lat":51.05, "lon":-1.35 }
2016-04-01 18:31:07 +08:00
2018-10-26 05:12:29 +08:00
`name` must be a unique identifier across the whole map. Repeated location updates to the same `name` move the marker.
2016-04-01 18:31:07 +08:00
Optional properties include
2018-06-01 16:34:48 +08:00
- **deleted** : set to < i > true</ i > to remove the named marker. (default < i > false</ i > )
2018-08-21 21:45:43 +08:00
- **draggable** : set to < i > true</ i > to allow marker to be moved. (default < i > false</ i > )
2019-05-30 02:22:29 +08:00
- **layer** : specify a layer on the map to add marker to. (default < i > "unknown"</ i > )
2019-02-17 01:40:28 +08:00
- **speed** : when combined with bearing, draws a vector.
- **bearing** : when combined with speed, draws a vector.
- **accuracy** : when combined with bearing, draws a polygon of possible direction.
2019-06-14 04:26:27 +08:00
- **color** : CSS color name or #rrggbb value for bearing line or accuracy polygon
2019-04-12 16:50:55 +08:00
- **icon** : < a href = "https://fontawesome.com/v4.7.0/icons/" target = "mapinfo" > font awesome</ a > icon name, < a href = "https://github.com/Paul-Reed/weather-icons-lite" target = "mapinfo" > weather-lite</ a > icon, :emoji name:, or http://
2018-01-03 16:31:02 +08:00
- **iconColor** : Standard CSS colour name or #rrggbb hex value.
2019-02-17 01:40:28 +08:00
- **SIDC** : NATO symbology code (can be used instead of icon). See below.
2018-06-01 05:50:50 +08:00
- **building** : OSMbulding GeoJSON feature set to add 2.5D buildings to buildings layer. See below.
2019-02-07 18:58:49 +08:00
- **ttl** : time to live, how long an individual marker stays on map in seconds (overrides general maxage setting, minimum 20 seconds)
2016-06-06 01:37:17 +08:00
- **photoUrl** : adds an image pointed at by the url to the popup box.
2017-12-14 06:16:09 +08:00
- **videoUrl** : adds an mp4 video pointed at by the url to the popup box. Ideally 320x240 in size.
2019-02-17 01:40:28 +08:00
- **weblink** : adds a link to an external page for more information. Either set a url as a *string* , or an *object* like `{"name":"BBC News", "url":"http://news.bbc.co.uk", "target":"_new"}`
- **addtoheatmap** : set to < i > false</ i > to exclude point from contributing to the heatmap layer. (default true)
- **intensity** : set to a value of 0.1 - 1.0 to set the intensity of the point on the heatmap layer. (default 1.0)
2018-11-09 19:16:45 +08:00
- **popped** : set to true to automatically open the popup info box, set to false to close it.
2019-07-01 01:30:24 +08:00
- **popup** : html to fill the popup if you don't want the automatic default of the properties list. Using this overrides photourl, videourl and weblink options.
2019-03-10 22:23:53 +08:00
- **label** : displays the contents as a permanent label next to the marker, or
- **tooltip** : displays the contents when you hover over the marker. (Mutually exclusive with label. Label has priority)
2019-03-18 17:03:04 +08:00
- **contextmenu** : an html fragment to display on right click of marker - defaults to delete marker. You can specify `$name` to pass in the name of the marker. Set to `""` to disable just this instance.
2017-04-20 20:44:19 +08:00
2019-07-01 01:30:24 +08:00
Any other `msg.payload` properties will be added to the icon popup text box. This can be
overridden by using the **popup** property to supply your own html content. If you use the
popup property it will completely replace the contents so photourl, videourl and weblink are
meaningless in this mode.
2016-04-01 18:31:07 +08:00
2018-05-18 16:59:46 +08:00
### Icons
2018-10-09 00:41:03 +08:00
You may select any of the Font Awesome set of [icons ](https://fontawesome.com/v4.7.0/icons/ ).
2019-04-12 16:50:55 +08:00
If you use the name without the fa- prefix (eg `male` ) you will get the icon inside a generic marker shape. If you use the fa- prefix (eg `fa-male` ) you will get the icon on its own. Likewise you can use any of the [Weather-lite ](https://github.com/Paul-Reed/weather-icons-lite ) icons by using the wi- prefix. These map to icons returned by common weather API such as DarkSky and OpenWeatherMap - for example `"wi-owm-"+msg.payload.weather[0].icon` will pickup the icon returned from the OpenWeatherMap API.
2017-07-13 00:59:56 +08:00
2019-02-12 00:40:34 +08:00
You can also specify an emoji as the icon by using the :emoji name: syntax - for example `:smile:` . Here is a ** [list of emojis ](https://github.com/dceejay/RedMap/blob/master/emojilist.md )**.
2019-03-03 07:21:47 +08:00
Or you can specify an image to load as an icon by setting the icon to http(s)://... It will be scaled to 32x32 pixels. For example `"https://img.icons8.com/windows/32/000000/bird.png"`
2017-07-13 00:59:56 +08:00
There are also several special icons...
2016-04-01 18:31:07 +08:00
- **plane** : a plane icon that aligns with the bearing of travel.
2016-04-01 18:43:24 +08:00
- **ship** : a ship icon that aligns with the bearing of travel.
2016-04-18 23:57:31 +08:00
- **car** : a car icon that aligns with the bearing of travel.
2017-06-28 16:01:03 +08:00
- **uav** : a small plane icon that aligns with the bearing of travel.
2019-04-26 06:57:23 +08:00
- **helicopter** : a small helicopter icon that aligns with the bearing of travel.
2017-06-26 23:21:55 +08:00
- **arrow** : a map GPS arrow type pointer that aligns with the bearing of travel.
- **wind** : a wind arrow that points in the direction the wind is coming FROM.
2018-05-18 16:59:46 +08:00
- **satellite** : a small satellite icon.
2018-07-16 22:52:33 +08:00
- **iss** : a slightly larger icon for the ISS.
2016-06-06 01:37:17 +08:00
- **locate** : a 4 corner outline to locate a point without obscuring it.
2018-05-18 16:19:47 +08:00
- **friend** : pseudo NATO style blue rectangle.
- **hostile** : pseudo NATO style red circle.
- **neutral** : pseudo NATO style green square.
- **unknown** : pseudo NATO style yellow square.
2018-05-18 16:59:46 +08:00
- **earthquake** : black circle - diameter proportional to `msg.mag` .
2016-04-01 18:31:07 +08:00
2018-06-01 00:32:29 +08:00
#### NATO Symbology
2018-06-02 01:49:08 +08:00
You can use NATO symbols from < a href = "https://github.com/spatialillusions/milsymbol" target = "mapinfo" > milsymbol.js< / a > .
2018-06-01 00:32:29 +08:00
To do this you need to supply a `msg.SIDC` instead of an icon, for example:
2019-02-21 20:39:09 +08:00
msg.payload = { "name": "Emergency Medical Operation",
"lat": 51.05,
"lon": -1.35,
"SIDC": "ENOPA-------",
"options": { "fillOpacity":0.8 }
2018-06-01 00:32:29 +08:00
}
2018-06-01 21:04:06 +08:00
SIDC codes can be generated using the online tool - https://spatialillusions.com/unitgenerator/
2018-06-02 01:49:08 +08:00
There are lots of extra options you can specify as `msg.options` - see the < a href = "https://github.com/spatialillusions/milsymbol/tree/master/docs" target = "mapinfo" > milsymbol docs here</ a > .
2018-06-01 05:50:50 +08:00
2018-05-29 16:04:32 +08:00
### Buildings
2019-02-17 01:40:28 +08:00
The OSM Buildings layer is available in the layers menu. You can replace this with a
building of your own by sending a `msg.payload.command.map` containing an `overlay`
and a `geojson` property. The geojson property should be a GeoJSON Feature Collection
2019-02-21 20:39:09 +08:00
as per the OSMBuildings spec. For example in a function node:
2018-07-04 16:05:41 +08:00
var geo = { "type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
2018-07-05 15:55:39 +08:00
"color": "rgb(0,0,255)",
"roofColor": "rgb(128,128,255)",
2018-07-04 16:05:41 +08:00
"height": 20,
2018-07-05 15:55:39 +08:00
"minHeight": 0
2018-07-04 16:05:41 +08:00
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-1.356221,51.048611],
[-1.356039,51.048672],
[-1.355765,51.048311],
[-1.355937,51.048237],
[-1.356221,51.048611]
]
]
}
}
]
2018-05-29 16:04:32 +08:00
}
2018-07-05 15:55:39 +08:00
var m = {overlay:"Golf Clubhouse", geojson:geo, fit:true};
2018-07-04 16:05:41 +08:00
msg.payload = {command:{map:m, lat:51.0484, lon:-1.3558}};
return msg;
2018-05-29 16:04:32 +08:00
**Note**: the object you supply will replace the whole buildings layer. To delete the building send a msg with a name and the building property set to "" (blank string).
2018-07-01 23:35:35 +08:00
#### Buildings 3D view
2018-07-04 16:05:41 +08:00
A 3D map view has now been added as **worldmap/index3d.html** using the mapbox api - the msg can support `msg.command.pitch` and `msg.command.bearing` to angle the view, for example:
2018-07-01 23:35:35 +08:00
2019-02-21 20:39:09 +08:00
msg.payload = { "command": { "zoom":18, "pitch":60, "bearing":80 } }
2018-07-01 23:35:35 +08:00
The `icon` can be specified as a person, block, bar, or "anything else" - they will render slightly differently - all units are approximate. They will be positioned at the `lat` , `lon` as normal but also at the `msg.payload.height` - where height is in meters above the surface of the map (which may or may not relate to altitude...)
`msg.payload.icon` can be
- person : 1m x 1m x 2m tall
- block : 5m x 5m x 5m cube
- bar : a bar from the surface up to the specified minHeight
- (else) : 1.5m x 1.5m x 1.5m cube
in addition existing male, female, fa-male and fa-female icons are all represented as the person shape.
`msg.iconColor` can be used to colour the icons.
**NOTES**
- There is currently no way to add labels, popups, or make the icons clickable.
- The 3D only really works at zoomed in scales 16+ due to the small size of the icons. They are not scale independent like icons on the normal map.
- As this uses the mapbox api you may wish to edit the index3d.html code to include your api key to remove any usage restrictions.
2019-02-17 01:40:28 +08:00
- This view is a side project to the Node-RED Worldmap project so I'm happy to take PRs but it probably won't be actively developed.
2018-05-29 16:04:32 +08:00
2019-04-30 18:41:00 +08:00
### Areas, Lines and Rectangles
2016-05-31 16:21:25 +08:00
2019-02-17 01:40:28 +08:00
If the msg.payload contains an **area** property - that is an array of co-ordinates, e.g.
2016-04-01 18:31:07 +08:00
2019-04-30 18:41:00 +08:00
msg.payload = {"name": "zone1", "area": [ [51.05, -0.08], [51.5, -1], [51.2, -0.047] ]}
2016-04-01 18:31:07 +08:00
2019-04-30 18:41:00 +08:00
then rather than draw a point and icon it draws the polygon. If the "area" array only has 2
elements, then it assumes this is a bounding box for a rectangle and draws a rectangle.
Likewise if it contains a **line** property it will draw the polyline.
There are extra optional properties you can specify - see Options below.
2016-04-01 18:31:07 +08:00
2019-04-24 06:56:14 +08:00
### Circles and Ellipses
2016-09-06 20:47:58 +08:00
2019-02-17 01:40:28 +08:00
If the msg.payload contains a **radius** property, as well as name, lat and lon, then rather
2017-06-28 15:53:12 +08:00
than draw a point it will draw a circle. The *radius* property is specified in meters.
2016-09-06 20:47:58 +08:00
2019-02-21 20:39:09 +08:00
msg.payload = { "name":"A3090", "lat":51.05, "lon":-1.35, "radius":3000 }
2018-05-18 16:19:47 +08:00
2019-05-01 19:31:58 +08:00
As per Areas and Lines you may also specify *color* , *fillColor* , and *layer* , see Options below.
2016-09-06 20:47:58 +08:00
2019-04-24 06:56:14 +08:00
If the **radius** property is an array of two numbers, these specify the minor and major radii
of an ellipse, in meters. A **tilt** property can also be applied to rotate the ellipse by
a number of degrees.
msg.payload = { "name":"Bristol Channel", "lat":51.5, "lon":-2.9, "radius":[30000,70000], "tilt":45 };
2017-06-28 15:53:12 +08:00
2018-05-18 16:59:46 +08:00
### Options
2017-06-26 23:19:05 +08:00
2019-04-30 18:41:00 +08:00
Areas, Rectangles, Lines, Circles and Ellipses can also specify more optional properties:
- **layer** : declares which layer you put it on.
- **color** : can set the colour of the polygon or line.
- **fillColor** : can set the fill colour of the polygon.
- **fillOpacity** : can set the opacity of the polygon fill colour.
- **dashArray** : optional dash array for polyline.
- **clickable** : boolean - set to true to allow click to show popup.
- **popup** : html string to display in popup (as well as name).
2019-05-01 19:31:58 +08:00
- **editable** : boolean - set to true to allow simple edit/delete right click contextmenu
- **contextmenu** : html string to display a more complex right click contextmenu
2019-04-30 18:41:00 +08:00
- **weight** : the width of the line (or outline)
Other properties can be found in the leaflet documentation.
2017-06-26 23:19:05 +08:00
2018-05-18 16:59:46 +08:00
## Drawing
2016-04-08 04:35:43 +08:00
2016-06-06 01:37:17 +08:00
A single *right click* will allow you to add a point to the map - you must specify the `name` and optionally the `icon` and `layer` .
2016-04-08 04:35:43 +08:00
Right-clicking on an icon will allow you to delete it.
2019-04-30 18:41:00 +08:00
If you select the **drawing** layer you can also add and edit polylines, polygons, rectangles and circles.
2019-05-01 19:31:58 +08:00
Once an item is drawn you can right click to edit or delete it. Double click the object to exit edit mode.
2016-04-08 04:35:43 +08:00
2019-02-17 01:40:28 +08:00
## Events from the map
The **worldmap in** node can be used to receive various events from the map. Examples of messages coming FROM the map include:
2019-02-17 01:58:41 +08:00
{ "action": "connected" } // useful to trigger delivery or redraw of points
{ "action": "disconnect", "clients": 1 } // when a client disconnects - reports number remaining
{ "action": "click", "name":"Jason", "layer":"gps", "icon":"male", "iconColor":"blue", "lat":51.024985, "lon":-1.39698 } // when a marker is clicked
{ "action": "move", "name":"Jason", "layer":"gps", "icon":"male", "iconColor":"blue", "lat":51.044632, "lon":-1.359901 } // when a marker is moved
2019-02-17 17:40:26 +08:00
{ "action": "delete", "name": "Jason" } // when a point or shape is deleted
2016-04-08 04:35:43 +08:00
2019-02-17 17:40:26 +08:00
{ "action": "point", "lat": "50.60634", "lon": "-1.66580", "point": "Jason,male,gps" }
2016-06-02 00:19:04 +08:00
{ "action": "draw", "type": "rectangle", "points": [ { "lat": 50.61243889044519, "lng": -1.5913009643554688 }, { "lat": 50.66665471366635, "lng": -1.5913009643554688 }, { "lat": 50.66665471366635, "lng": -1.4742279052734375 }, { "lat": 50.61243889044519, "lng": -1.4742279052734375 } ] }
2019-02-17 01:40:28 +08:00
{ "action": "layer", "name": "myLayer" } // when a map layer is changed
{ "action": "addlayer", "name": "myLayer" } // when a new map layer is added
{ "action": "dellayer", "name": "myLayer" } // when a new map layer is deleted
2016-04-08 04:35:43 +08:00
2019-02-21 20:22:51 +08:00
{ "action": "button", "name": "My Fancy Button" } // when a user defined button is clicked
2019-03-10 22:23:53 +08:00
{ "action": "feedback", "name": "some name", "value": "some value" } // when a user calls the feedback function - see below
2019-04-22 01:31:06 +08:00
All actions also include a `msg._sessionid` property that indicates which client session they came from. Any msg sent out that includes this property will ONLY be sent to that session - so you can target map updates to specific sessions if required.
2019-02-17 01:58:41 +08:00
2019-05-01 19:31:58 +08:00
### Utility functions
There are some internal functions available to make interacting with Node-RED easier (e.g. from inside a user defined popup., these include:
- **feedback()** : it takes two (or three) parameters, name, value, and optionally an action name (defaults to "feedback"), and can be used inside something like an input tag - `onchange='feedback(this.name,this.value)'` . Value can be a more complex object if required as long as it is serialisable.
- **delMarker()** : takes the name of the marker as a parameter. In a popup this can be specified as `$name` for dynamic substitution.
- **editPoly()** : takes the name of the shape or line as a parameter. In a popup this can be specified as `$name` for dynamic substitution.
2019-02-17 01:40:28 +08:00
## Controlling the map
2016-04-01 18:31:07 +08:00
2018-12-23 22:30:26 +08:00
You can also control the map via the node, by sending in a msg.payload containing a **command** object. Multiple parameters can be specified in one command.
2016-04-01 18:31:07 +08:00
Optional properties include
- **lat** - move map to specified latitude.
- **lon** - move map to specified longitude.
- **zoom** - move map to specified zoom level (1 - world, 13 to 20 max zoom depending on map).
2019-02-17 01:40:28 +08:00
- **layer** - set map to specified base layer name - `{"command":{"layer":"Esri"}}`
- **search** - search markers on map for name containing `string` . If not found in existing markers, will then try geocoding looking using Nominatim. An empty string `""` clears the search results. - `{"command":{"search":"Winchester"}}`
- **showlayer** - show the named overlay(s) - `{"command":{"showlayer":"foo"}}` or `{"command":{"showlayer":["foo","bar"]}}`
- **hidelayer** - hide the named overlay(s) - `{"command":{"hidelayer":"bar"}}` or `{"command":{"hidelayer":["bar","another"}}`
- **side** - add a second map alongside with slide between them. Use the name of a *baselayer* to add - or "none" to remove the control. - `{"command":{"side":"Esri Satellite"}}`
- **split** - once you have split the screen - the split value is the % across the screen of the split line. - `{"command":{"split":50}}`
2016-04-01 18:31:07 +08:00
- **map** - Object containing details of a new map layer:
2016-06-02 00:19:04 +08:00
- **name** - name of the map base layer OR **overlay** - name of overlay layer
2016-04-01 18:31:07 +08:00
- **url** - url of the map layer
- **opt** - options object for the new layer
2019-03-30 02:26:55 +08:00
- **wms** - true/false/grey, specifies if the data is provided by a Web Map Service (if grey sets layer to greyscale)
2019-02-17 01:40:28 +08:00
- **bounds** - sets the bounds of an Overlay-Image. 2 Dimensional Array that defines the top-left and bottom-right Corners (lat/lon Points)
2019-03-19 21:53:06 +08:00
- **delete** - name or array of names of base layers and/or overlays to delete and remove from layer menu.
2017-03-04 22:13:05 +08:00
- **heatmap** - set heatmap options object see https://github.com/Leaflet/Leaflet.heat#reference
2019-06-21 06:13:24 +08:00
- **clear** - layer name - to clear a complete layer and remove from layer menu - `{"command":{"clear":"myOldLayer"}}`
2019-02-17 01:40:28 +08:00
- **panlock** - lock the map area to the current visible area. - `{"command":{"panlock":true}}`
- **zoomlock** - locks the zoom control to the current value and removes zoom control - `{"command":{"zoomlock":true}}`
2019-02-28 06:05:02 +08:00
- **hiderightclick** - disables the right click that allows adding or deleting points on the map - `{"command":{"hiderightclick":true}}`
2019-03-11 02:29:44 +08:00
- **coords** - turns on and off a display of the current mouse co-ordinates. Values can be "deg", "dms", or "none" (default). - `{"command":{"coords":"deg"}}`
2019-02-21 20:22:51 +08:00
- **button** - if supplied with a `name` and `icon` property - adds a button to provide user input - sends
2019-03-18 17:03:04 +08:00
a msg `{"action":"button", "name":"the_button_name"}` to the worldmap in node. If supplied with a `name` property only, it will remove the button. Optional `position` property can be 'bottomright', 'bottomleft', 'topleft' or 'topright' (default).
- **contextmenu** - html string to define the right click menu when not on a marker. Defaults to the simple add marker input. Empty string `""` disables this right click.
2016-04-01 18:31:07 +08:00
2018-05-18 16:31:35 +08:00
#### To switch layer, move map and zoom
2016-04-01 18:31:07 +08:00
2019-03-12 01:33:53 +08:00
msg.payload = { "command": { "layer":"Esri Satellite", "lat":51, "lon":3, "zoom":10 }};
You can also use the name "none" to completely remove the base layer,
msg.payload = { "command": { "layer":"none" }};
2016-04-01 18:31:07 +08:00
2019-02-21 20:39:09 +08:00
#### To add and remove a user defined button
2019-02-21 20:22:51 +08:00
to add a button bottom right
2019-02-21 20:39:09 +08:00
msg.payload.command = { "button": { "name":"My Fancy Button", "icon": "fa-star", "position":"bottomright" } };
2019-02-21 20:22:51 +08:00
When clicked the button will send an event to the `worldmap in` node containing `{"action":"button", "name","My Fancy Button"}` - this can then be used to trigger other map commands or flows.
to remove
2019-02-21 20:39:09 +08:00
msg.payload.command = { "button": { "name":"My Fancy Button" } };
2019-02-21 20:22:51 +08:00
2019-03-25 08:17:08 +08:00
#### To add a custom popup or contextmenu
You can customise a marker's popup, or context menu (right click), by setting the
appropriate property to an html string. Often you will need some embedded javascript
in order to make it do something when you click a button for example. You need to be
careful escaping quotes, and that they remain matched.
For example a popup with a slider (note the \ escaping the internal ' )
popup: '< input name = "slide1" type = "range" min = "1" max = "100" value = "50" onchange = \'feedback(this.name,this.value) \' style = "width:250px;" > '
Or a contextmenu with a button
contextmenu: '< button name = "Clicker" onclick = \'feedback(this.name) \'> Click me</ button > '
#### To draw a heavily customised Circle on a layer
2017-06-28 15:53:12 +08:00
2018-06-01 06:02:01 +08:00
msg.payload.command = {
2019-02-21 20:39:09 +08:00
"name": "circle",
"lat": 51.515,
"lon": -0.1235,
"radius": 10,
"layer": "drawing",
"iconColor": '#464646',
"stroke": false,
"fillOpacity": 0.8,
"clickable": true
2018-06-01 06:02:01 +08:00
};
2017-06-28 15:53:12 +08:00
2018-05-18 16:31:35 +08:00
#### To add a new base layer
2016-04-01 18:31:07 +08:00
2018-10-03 01:54:09 +08:00
The layer will be called `name` . By default it expects a leaflet Tilelayer style url. You can also use a WMS
2019-03-30 02:26:55 +08:00
style server by adding a property `wms: true` . You can also set `wms: "grey"` to set the layer to greyscale which
may let you markers be more visible. (see overlay example below).
2018-10-03 01:54:09 +08:00
2018-06-01 06:02:01 +08:00
msg.payload.command.map = {
2019-02-21 20:39:09 +08:00
"name":"OSMhot",
2019-03-11 20:59:09 +08:00
"url":"https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png",
2019-02-21 20:39:09 +08:00
"opt":{ "maxZoom":19, "attribution":"© OpenStreetMap" }
2018-06-01 06:02:01 +08:00
};
2016-04-01 18:31:07 +08:00
2019-03-19 22:25:04 +08:00
#### To remove base or overlay layers
To remove several layers, either base layers or overlays, you can pass an array of names as follows.
2019-03-25 08:17:08 +08:00
This can be used to tidy up the initial selections available to the user layer menu.
2019-03-19 22:25:04 +08:00
msg.payload.command.map = {
2019-05-07 19:33:18 +08:00
"delete":["Watercolor","ship nav","heatmap","Terrain","UK OS 1900","UK OS 1919-47"]
2019-03-19 22:25:04 +08:00
};
2019-05-07 19:43:22 +08:00
Note: layer names are case sensitive.
2018-10-03 01:54:09 +08:00
#### To add a WMS overlay layer - eg US weather radar
To add an overlay instead of a base layer - specify the `overlay` property instead of the `name` .
msg.payload.command.map = {
2019-02-21 20:39:09 +08:00
"overlay": "NowCoast",
"url": "https://nowcoast.noaa.gov/arcgis/services/nowcoast/radar_meteo_imagery_nexrad_time/MapServer/WmsServer?",
"opt": {
"layers": "1",
2019-04-03 00:44:57 +08:00
"format": "image/png",
2019-02-21 20:39:09 +08:00
"transparent": true,
"attribution": "NOAA/NWS"
2018-10-03 01:54:09 +08:00
},
2019-02-21 20:39:09 +08:00
"wms": true
2018-10-03 01:54:09 +08:00
}
2019-08-17 00:25:45 +08:00
By default the overlay will be instantly visible. To load it hidden add a property to the command.map - `visible:false`
2018-05-18 16:31:35 +08:00
#### To add a new geoJSON overlay
2018-01-03 16:31:02 +08:00
2018-06-01 06:02:01 +08:00
msg.payload.command.map = {
2019-02-21 20:39:09 +08:00
"overlay": "myGeoJSON",
"geojson": { your geojson feature as an object },
"opt": { optional geojson options, style, etc },
"fit": true
2018-06-01 06:02:01 +08:00
};
2018-01-03 16:31:02 +08:00
2018-09-21 05:26:17 +08:00
The geojson features may contain a `properties` property. That may also include a `style` with properties - stroke, stroke-width, stroke-opacity, fill, fill-opacity. Any other properties will be listed in the popup.
The `opt` property is optional. See the < a href = "https://leafletjs.com/examples/geojson/" > Leaflet geojson docs</ a > for more info on possible options. Note: only simple options are supported as functions cannot be serialised.
2018-06-27 03:42:24 +08:00
2019-08-08 04:56:26 +08:00
The `fit` property is optional. If boolean true the map will automatically zoom to fit the area relevant to the geojson.
2019-02-17 01:40:28 +08:00
2018-06-27 03:42:24 +08:00
see http://leafletjs.com/examples/geojson/ for more details about options for opt.
#### To add a new KML, GPX, or TOPOJSON overlay
2018-09-21 05:26:17 +08:00
As per the geojson overlay you can also inject a KML layer, GPX layer or TOPOJSON layer. The syntax is the same but with either a `kml` property containing the KML string - a `gpx` property containing a GPX string - or a `topojson` property containing the topojson.
2018-06-27 03:42:24 +08:00
msg.payload.command.map = {
2019-02-21 20:39:09 +08:00
"overlay": "myKML",
"kml": "< kml > ...your kml placemarks...< / kml > "
2018-06-27 03:42:24 +08:00
};
2018-09-21 05:26:17 +08:00
For GPX and KML layers, it is possible to define which icon to use for point markers by adding the
2018-09-21 03:47:47 +08:00
following properties to `msg.payload.command.map` :
2019-02-17 01:40:28 +08:00
2018-09-21 05:26:17 +08:00
- **icon** : < a href = "https://fontawesome.com/v4.7.0/icons/" target = "mapinfo" > font awesome</ a > icon name.
2018-09-21 03:47:47 +08:00
- **iconColor** : Standard CSS colour name or #rrggbb hex value.
2019-08-17 00:25:45 +08:00
Again the boolean `fit` property can be added to make the map zoom to the relevant area, and the `visible` property can be set false to not immediately show the layer.
2018-01-03 16:31:02 +08:00
2018-06-03 23:12:13 +08:00
#### To add a Velocity Grid Overlay
msg.payload.command.map = {
2019-02-21 20:39:09 +08:00
"overlay": "myWind",
"velocity": {
"displayValues": true,
"displayOptions": {
"velocityType": "Global Wind",
"displayPosition": "bottomleft",
"displayEmptyString": "No wind data"
2018-06-03 23:12:13 +08:00
},
2019-02-21 20:39:09 +08:00
"maxVelocity": 15,
"data": [Array of data as per format referenced below]
2018-06-03 23:12:13 +08:00
}
};
see https://github.com/danwild/leaflet-velocity for more details about options and data examples.
2018-05-18 16:31:35 +08:00
#### To add an Image Overlay
2017-07-13 00:59:56 +08:00
2019-02-21 20:39:09 +08:00
in a function node:
2018-06-01 06:02:01 +08:00
var imageBounds = [[40.712216, -74.22655], [40.773941, -74.12544]];
2019-02-21 20:39:09 +08:00
msg.payload = { command : { lat:40.74, lon:-74.175, zoom:13 } };
2018-06-01 06:02:01 +08:00
msg.payload.command.map = {
2019-02-17 01:40:28 +08:00
overlay: "New York Historical",
2019-03-11 20:59:09 +08:00
url: 'https://www.lib.utexas.edu/maps/historical/newark_nj_1922.jpg',
2018-06-01 06:02:01 +08:00
bounds: imageBounds,
2019-03-12 01:33:53 +08:00
opt: { opacity:0.8, attribution:"© University of Texas" }
2018-06-01 06:02:01 +08:00
};
2017-06-28 15:53:12 +08:00
2019-04-22 05:32:01 +08:00
#### To add a Lat/Lon Graticule overlay
A graticule can be enabled via the node configuration, and can also be set dynamically,
for example in a function node:
msg.payload = { command : { grid : {
showgrid: true,
opt: { showLabel:true, dashArray:[5, 5], fontColor:"#900" }
};
see https://github.com/cloudybay/leaflet.latlng-graticule for more details about options and demo.
2019-03-12 01:33:53 +08:00
#### To clear all markers from a layer, or an overlay from the map
2018-05-18 16:19:47 +08:00
2019-06-21 06:13:24 +08:00
msg.payload.command.clear = "name of the layer/overlay you wish to clear";
Feeding this into the tracks node will also remove the tracks stored for that layer.
2018-05-18 16:19:47 +08:00
2017-04-20 20:44:19 +08:00
### Using a local Map Server (WMS server)
2018-06-02 01:49:08 +08:00
IMHO the easiest map server to make work is the < a href = "http://www.mapserver.org/" target = "mapinfo" > mapserver< / a > package in Ubuntu / Debian. Usually you will start with
2017-04-20 20:44:19 +08:00
sudo apt-get install mapserver-bin cgi-mapserver gdal-bin
Configuring that, setting up your tiles, and creating a .map file is way beyond the scope of this README so I will leave that as an exercise for the reader. Once set up you should have a cgi process you can run called `mapserv` , and a `.map` file that describes the layers available from the server.
2018-05-18 16:31:35 +08:00
Create and edit these into an executeable file called **mapserv** , located in this node's directory, typically
2017-04-20 20:44:19 +08:00
`~/.node-red/node_modules/node-red-contrib-web-worldmap/mapserv` , for example:
#! /bin/sh
# set this to the path of your WMS map file (which in turn points to your tiles)
2019-03-24 06:30:49 +08:00
MS_MAPFILE=/home/pi/maps/gb.map
2017-04-20 20:44:19 +08:00
export MS_MAPFILE
# and set this to the path of your cgi-mapserv executable
/usr/bin/mapserv
You can then add a new WMS Base layer by injecting a message like
2019-03-24 06:30:49 +08:00
msg.payload = { command : { map : {
2019-02-21 20:39:09 +08:00
"name": "Local WMS",
2019-03-24 06:30:49 +08:00
"url": "/cgi-bin/mapserv", // we will serve the tiles from this node locally.
2019-02-21 20:39:09 +08:00
"opt": {
2019-03-24 06:30:49 +08:00
"layers": "gb", // specifies a layer in your map file
2019-02-21 20:39:09 +08:00
"format": "image/png",
"transparent": true,
"attribution": "© Ordnance Survey, UK"
2017-04-20 20:44:19 +08:00
},
2019-03-24 06:30:49 +08:00
"wms": true // set to true for WMS type mapserver
}}}
2017-04-20 20:44:19 +08:00
2019-03-30 02:26:55 +08:00
Optionally set `"wms":"grey"` to make the layer to greyscale which may make your markers more visible.
2017-04-20 20:44:19 +08:00
2018-05-18 16:59:46 +08:00
## Demo Flow
2016-04-01 18:31:07 +08:00
The following example gets recent earthquakes from USGS, parses the result,
2016-05-31 16:21:25 +08:00
formats up the msg as per above and sends to the node to plot on the map.
2016-04-01 18:31:07 +08:00
It also shows how to zoom and move the map or add a new layer.
2018-07-04 18:02:55 +08:00
[{"id":"86457344.50e6b","type":"inject","z":"745a133b.dd6dec","name":"","topic":"","payload":"","payloadType":"none","repeat":"","crontab":"","once":false,"x":190,"y":2420,"wires":[["9a142026.fa47f"]]},{"id":"9a142026.fa47f","type":"function","z":"745a133b.dd6dec","name":"add new layer","func":"msg.payload = {};\nmsg.payload.command = {};\n\nvar u = 'http://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png';\nvar o = { maxZoom: 19, attribution: '© OpenStreetMap'};\n\nmsg.payload.command.map = {name:\"OSMhot\", url:u, opt:o};\nmsg.payload.command.layer = \"OSMhot\";\n\nreturn msg;","outputs":1,"noerr":0,"x":420,"y":2420,"wires":[["c643e022.1816c"]]},{"id":"c643e022.1816c","type":"worldmap","z":"745a133b.dd6dec","name":"","x":750,"y":2460,"wires":[]},{"id":"2998e233.4ba64e","type":"function","z":"745a133b.dd6dec","name":"USGS Quake monitor csv re-parse","func":"msg.payload.lat = msg.payload.latitude;\nmsg.payload.lon = msg.payload.longitude;\nmsg.payload.layer = \"earthquake\";\nmsg.payload.name = msg.payload.id;\nmsg.payload.icon = \"globe\";\nmsg.payload.iconColor = \"orange\";\n\ndelete msg.payload.latitude;\ndelete msg.payload.longitude;\t\nreturn msg;","outputs":1,"noerr":0,"x":540,"y":2560,"wires":[["c643e022.1816c"]]},{"id":"e72c5732.9fa198","type":"function","z":"745a133b.dd6dec","name":"move and zoom","func":"msg.payload = { command:{layer:\"Esri Terrain\",lat:0,lon:0,zoom:3} };\nreturn msg;","outputs":1,"noerr":0,"x":420,"y":2460,"wires":[["c643e022.1816c"]]},{"id":"12317723.589249","type":"csv","z":"745a133b.dd6dec","name":"","sep":",","hdrin":true,"hdrout":"","multi":"one","ret":"\\n","temp":"","x":390,"y":2500,"wires":[["2998e233.4ba64e"]]},{"id":"10e5e5f0.8daeaa","type":"inject","z":"745a133b.dd6dec","name":"","topic":"","payload":"","payloadType":"none","repeat":"","crontab":"","once":false,"x":190,"y":2460,"wires":[["e72c5732.9fa198"]]},{"id":"b6917d83.d1bac","type":"http request","z":"745a133b.dd6dec","name":"","method":"GET","url":"http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_day.csv","x":270,"y":2560,"wires":[["12317723.589249"]]},{"id":"3842171.4d487e8","type":"inject","z":"745a133b.dd6dec","name":"Quakes","topic":"","payload":"","payloadType":"none","repeat":"900","crontab":"","once":false,"x":200,"y":2500,"wires":[["b6917d83.d1bac"]]}]
2016-04-18 23:57:31 +08:00
2019-09-29 17:23:19 +08:00
Car and Helicopter icons made by < a href = "http://www.freepik.com" title = "Freepik" > Freepik< / a > from < a href = "http://www.flaticon.com" title = "Flaticon" > www.flaticon.com< / a > is licensed by < a href = "http://creativecommons.org/licenses/by/3.0/" title = "Creative Commons BY 3.0" target = "mapinfo" > CC 3.0 BY< / a > .