Merge branch 'master' into leaflet-upgrade
This commit is contained in:
commit
d4ce4ef023
@ -1,5 +1,9 @@
|
||||
### Change Log for Node-RED Worldmap
|
||||
|
||||
- v1.5.39 - Add weather-lite icons
|
||||
- v1.5.38 - Add Esri dark grey and ocean, re-add hikebike, layers
|
||||
- v1.5.37 - Add .trackpoints to override default number in tracks node. Let tracks optionally be on different layers. Fix marker changing layers Issue #85
|
||||
- v1.5.36 - Fix contextmenu $name substitution
|
||||
- v1.5.35 - Add msp.delete command to remove any layers not needed at start (array of names). Issue #83.
|
||||
- v1.5.34 - Add command.contextmenu to set non-marker context menu (defaults to add marker).
|
||||
- v1.5.33 - Let blank input disable contextmenu completely. Tidy up help, update dialog polyfill.
|
||||
|
62
README.md
62
README.md
@ -9,21 +9,16 @@ map web page for plotting "things" on.
|
||||
|
||||
### Updates
|
||||
|
||||
- v1.5.35 - Add msp.delete command to remove any layers not needed at start (array of names). Issue #83.
|
||||
- v1.5.39 - Add weather-lite icons
|
||||
- v1.5.38 - Add Esri dark grey and ocean, re-add hikebike, layers
|
||||
- v1.5.37 - Add .trackpoints to override default in tracks node. Let tracks optionally be on different layers. Fix marker changing layers Issue #85
|
||||
- v1.5.36 - Fix contextmenu $name substitution. Issue #84
|
||||
- v1.5.35 - Add msg.delete command to remove any layers not needed at start (array of names). Issue #83.
|
||||
- v1.5.34 - Add command.contextmenu to set non-marker context menu (defaults to add marker).
|
||||
- v1.5.33 - Let blank input disable contextmenu completely. Tidy up help, update dialog polyfill.
|
||||
- v1.5.32 - Add .contextmenu custom right click menu, Fix map lock, Close websocket on unload
|
||||
- v1.5.31 - Fix pan first at start, and coords overlay. Issues #81 and #82
|
||||
- v1.5.30 - Add .tooltip option, ability to remove base layer, search on icon, show mouse pointer co-ordinates
|
||||
- v1.5.29 - Remove lat/lon from popup if using .popup property. Allow icon to be loaded from http.
|
||||
- v1.5.28 - Tidy up popup location and timing. Auto add countries overlay if no internet.
|
||||
- v1.5.27 - Add hide right click option to config panel
|
||||
- v1.5.26 - Ensure all map tiles loaded over https
|
||||
- v1.5.25 - Add button command to allow user to add and remove buttons
|
||||
- v1.5.24 - Ensure hiderightclick does do that, and popup always has close button. Issue #69, #70
|
||||
- v1.5.23 - Let icon support use of emoji specified as :emoji name:
|
||||
- v1.5.22 - Slight adjust to label positions for default map marker icon. Add .lineColor for bearing lines
|
||||
- v1.5.21 - Add .label option to display permanent label. Clean up some excess debug logging
|
||||
- ...
|
||||
|
||||
see [CHANGELOG](https://github.com/dceejay/RedMap/blob/master/CHANGELOG.md) for full list.
|
||||
@ -58,7 +53,7 @@ Optional properties include
|
||||
- **bearing** : when combined with speed, draws a vector.
|
||||
- **accuracy** : when combined with bearing, draws a polygon of possible direction.
|
||||
- **lineColor** : CSS color name or #rrggbb value for bearing line or accuracy polygon
|
||||
- **icon** : <a href="https://fontawesome.com/v4.7.0/icons/" target="mapinfo">font awesome</a> icon name, :emoji name:, or http://
|
||||
- **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://
|
||||
- **iconColor** : Standard CSS colour name or #rrggbb hex value.
|
||||
- **SIDC** : NATO symbology code (can be used instead of icon). See below.
|
||||
- **building** : OSMbulding GeoJSON feature set to add 2.5D buildings to buildings layer. See below.
|
||||
@ -80,7 +75,7 @@ by using the **popup** property to supply your own html content.
|
||||
### Icons
|
||||
|
||||
You may select any of the Font Awesome set of [icons](https://fontawesome.com/v4.7.0/icons/).
|
||||
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.
|
||||
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.
|
||||
|
||||
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)**.
|
||||
|
||||
@ -256,7 +251,7 @@ The **worldmap in** node can be used to receive various events from the map. Exa
|
||||
|
||||
There is a function available to make sending date to Node-RED easier (e.g. from inside a user defined popup), called feedback() - it takes two parameters, name and value, 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.
|
||||
|
||||
All actions also include a `msg._sessionid` property that indicates which client session they came from. Any msg sent out that include this will ONLY to that session - so you can target map updates to certain sessions only if required.
|
||||
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 certain sessions only if required.
|
||||
|
||||
## Controlling the map
|
||||
|
||||
@ -277,7 +272,7 @@ Optional properties include
|
||||
- **name** - name of the map base layer OR **overlay** - name of overlay layer
|
||||
- **url** - url of the map layer
|
||||
- **opt** - options object for the new layer
|
||||
- **wms** - boolean, specifies if the data is provided by a Web Map Service
|
||||
- **wms** - true/false/grey, specifies if the data is provided by a Web Map Service (if grey sets layer to greyscale)
|
||||
- **bounds** - sets the bounds of an Overlay-Image. 2 Dimensional Array that defines the top-left and bottom-right Corners (lat/lon Points)
|
||||
- **delete** - name or array of names of base layers and/or overlays to delete and remove from layer menu.
|
||||
- **heatmap** - set heatmap options object see https://github.com/Leaflet/Leaflet.heat#reference
|
||||
@ -310,7 +305,23 @@ to remove
|
||||
|
||||
msg.payload.command = { "button": { "name":"My Fancy Button" } };
|
||||
|
||||
#### To draw a heavily customized Circle on a layer
|
||||
#### 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
|
||||
|
||||
msg.payload.command = {
|
||||
"name": "circle",
|
||||
@ -327,7 +338,8 @@ to remove
|
||||
#### To add a new base layer
|
||||
|
||||
The layer will be called `name`. By default it expects a leaflet Tilelayer style url. You can also use a WMS
|
||||
style server by adding a property `wms: true`. (see overlay example below)
|
||||
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).
|
||||
|
||||
msg.payload.command.map = {
|
||||
"name":"OSMhot",
|
||||
@ -338,7 +350,7 @@ style server by adding a property `wms: true`. (see overlay example below)
|
||||
#### To remove base or overlay layers
|
||||
|
||||
To remove several layers, either base layers or overlays, you can pass an array of names as follows.
|
||||
This can be useful tidy up the initial selections available to the user layer menu.
|
||||
This can be used to tidy up the initial selections available to the user layer menu.
|
||||
|
||||
msg.payload.command.map = {
|
||||
"delete":["Watercolor","Ship Nav","Heatmap"]
|
||||
@ -353,7 +365,7 @@ To add an overlay instead of a base layer - specify the `overlay` property inste
|
||||
"url": "https://nowcoast.noaa.gov/arcgis/services/nowcoast/radar_meteo_imagery_nexrad_time/MapServer/WmsServer?",
|
||||
"opt": {
|
||||
"layers": "1",
|
||||
"format": 'image/png",
|
||||
"format": "image/png",
|
||||
"transparent": true,
|
||||
"attribution": "NOAA/NWS"
|
||||
},
|
||||
@ -442,24 +454,26 @@ Create and edit these into an executeable file called **mapserv**, located in th
|
||||
|
||||
#! /bin/sh
|
||||
# set this to the path of your WMS map file (which in turn points to your tiles)
|
||||
MS_MAPFILE=~/Data/maps/uk.map
|
||||
MS_MAPFILE=/home/pi/maps/gb.map
|
||||
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
|
||||
|
||||
msg.payload.command.map = {
|
||||
msg.payload = { command : { map : {
|
||||
"name": "Local WMS",
|
||||
"url": "http://localhost:1880/cgi-bin/mapserv", // we will serve the tiles from this node locally.
|
||||
"url": "/cgi-bin/mapserv", // we will serve the tiles from this node locally.
|
||||
"opt": {
|
||||
"layers": "gb", // specifies a layer in your map file
|
||||
"layers": "gb", // specifies a layer in your map file
|
||||
"format": "image/png",
|
||||
"transparent": true,
|
||||
"attribution": "© Ordnance Survey, UK"
|
||||
},
|
||||
"wms": true // set to true for WMS type mapserver
|
||||
}
|
||||
"wms": true // set to true for WMS type mapserver
|
||||
}}}
|
||||
|
||||
Optionally set `"wms":"grey"` to make the layer to greyscale which may make your markers more visible.
|
||||
|
||||
|
||||
## Demo Flow
|
||||
|
@ -33,18 +33,20 @@
|
||||
<option value="OSM">OpenStreetMap</option>
|
||||
<option value="Esri">ESRI Streetmap</option>
|
||||
<option value="Esri Satellite">ESRI Satellite</option>
|
||||
<option value="Esri Terrain">ESRI Terrain</option>
|
||||
<option value="Esri Topography">ESRI Topography</option>
|
||||
// <option value="Esri Terrain">ESRI Terrain</option>
|
||||
<option value="Esri Dark Grey">ESRI Dark Grey</option>
|
||||
<option value="Esri Ocean">ESRI Ocean</option>
|
||||
<option value="Nat Geo">National Geographic</option>
|
||||
<option value="UK OS Opendata">UK OS Opendata</option>
|
||||
<!-- <option value="Hike Bike">Hike Bike OSM</option> -->
|
||||
<option value="Hike Bike">Hike Bike OSM</option>
|
||||
<option value="Terrain">Terrain</option>
|
||||
<option value="Watercolor">Stamen Watercolor</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-cluster"><i class="fa fa-gears"></i> Cluster if</label>
|
||||
zoom level is less than <input type="text" id="node-input-cluster" placeholder="13 (0-19)" style="width:80px;">
|
||||
<label for="node-input-cluster"><i class="fa fa-dot-circle-o"></i>Cluster when</label>
|
||||
zoom level is less than <input type="text" id="node-input-cluster" placeholder="0 (0,off - 19)" style="width:100px;">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-maxage"><i class="fa fa-clock-o"></i> Max age</label>
|
||||
@ -102,7 +104,7 @@
|
||||
<label for="node-input-name"><i class="fa fa-file"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="name">
|
||||
</div>
|
||||
<div class="form-tips">Set <i>Cluster if</i> to 0 to disable clustering of points.<br/>If <i>Path</i> is left empty,
|
||||
<div class="form-tips">Set <i>Cluster when</i> to 0 to disable clustering of points.<br/>If <i>Path</i> is left empty,
|
||||
then by default <code>⌘⇧m</code> - <code>ctrl-shift-m</code> will load the map in a new tab.</div>
|
||||
</script>
|
||||
|
||||
@ -268,6 +270,14 @@ then by default <code>⌘⇧m</code> - <code>ctrl-shift-m</code> will load the m
|
||||
<label for="node-input-depth"><i class="fa fa-map-marker"></i> Number of</label>
|
||||
points in track <input type="text" id="node-input-depth" style="width:50%" placeholder="number - default 20">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-layer"><i class="fa fa-map"></i> Track Layer</label>
|
||||
<select id="node-input-layer">
|
||||
<option value="combined">on marker layer</option>
|
||||
<option value="separate">one per marker layer</option>
|
||||
<option value="single">single Track layer</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-file"></i> Name</label>
|
||||
<input type="text" id="node-input-name" placeholder="name">
|
||||
@ -276,6 +286,8 @@ then by default <code>⌘⇧m</code> - <code>ctrl-shift-m</code> will load the m
|
||||
|
||||
<script type="text/x-red" data-help-name="worldmap-tracks">
|
||||
<p>Creates tracks lines based on a specified number of previous locations.</p>
|
||||
<p>The number of tracked points can be set per marker by specifying <code>msg.payload.trackpoints</code> as part of the update for a marker.</p>
|
||||
<p>You can also specify the msg.payload.color, weight, opacity and dashArray properties for the track if required.</p>
|
||||
<p>Holds all the points in memory, so if you have a lot of points held for a
|
||||
large depth then memory usage may become excessive.</p>
|
||||
<p>To delete a track send a msg.payload containing both the name of the object and
|
||||
@ -287,8 +299,9 @@ then by default <code>⌘⇧m</code> - <code>ctrl-shift-m</code> will load the m
|
||||
category: 'location',
|
||||
color:"darksalmon",
|
||||
defaults: {
|
||||
name: {value:""},
|
||||
depth: {value:20},
|
||||
name: {value:""}
|
||||
layer: {value:"combined"}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:1,
|
||||
|
52
worldmap.js
52
worldmap.js
@ -43,10 +43,10 @@ module.exports = function(RED) {
|
||||
this.path = n.path || "/worldmap";
|
||||
if (this.path.charAt(0) != "/") { this.path = "/" + this.path; }
|
||||
if (!sockets[this.path]) {
|
||||
var fullPath = path.posix.join(RED.settings.httpNodeRoot, this.path, 'leaflet', 'sockjs.min.js');
|
||||
sockets[this.path] = sockjs.createServer({sockjs_url:fullPath, log:function() { return; }});
|
||||
var libPath = path.posix.join(RED.settings.httpNodeRoot, this.path, 'leaflet', 'sockjs.min.js');
|
||||
var sockPath = path.posix.join(RED.settings.httpNodeRoot,this.path,'socket');
|
||||
sockets[this.path].installHandlers(RED.server, {prefix:sockPath});
|
||||
sockets[this.path] = sockjs.createServer({prefix:sockPath, sockjs_url:libPath, log:function() { return; }});
|
||||
sockets[this.path].installHandlers(RED.server);
|
||||
}
|
||||
//this.log("Serving "+__dirname+" as "+this.path);
|
||||
this.log("started at "+this.path);
|
||||
@ -103,6 +103,7 @@ module.exports = function(RED) {
|
||||
clients[c].end();
|
||||
}
|
||||
}
|
||||
clients = {};
|
||||
sockets[this.path].removeListener('connection', callback);
|
||||
for (var i=0; i < RED.httpNode._router.stack.length; i++) {
|
||||
var r = RED.httpNode._router.stack[i];
|
||||
@ -122,9 +123,9 @@ module.exports = function(RED) {
|
||||
this.path = n.path || "/worldmap";
|
||||
if (this.path.charAt(0) != "/") { this.path = "/" + this.path; }
|
||||
if (!sockets[this.path]) {
|
||||
var fullPath = path.posix.join(RED.settings.httpNodeRoot, this.path, 'leaflet', 'sockjs.min.js');
|
||||
// sockets[this.path] = sockjs.createServer({sockjs_url:fullPath, log:function() { return; }});
|
||||
sockets[this.path] = sockjs.createServer({sockjs_url:fullPath, log:function(){return}, prefix:path.posix.join(RED.settings.httpNodeRoot,this.path,'socket'), });
|
||||
var libPath = path.posix.join(RED.settings.httpNodeRoot, this.path, 'leaflet', 'sockjs.min.js');
|
||||
var sockPath = path.posix.join(RED.settings.httpNodeRoot,this.path,'socket');
|
||||
sockets[this.path] = sockjs.createServer({prefix:sockPath, sockjs_url:libPath, log:function() { return; }});
|
||||
sockets[this.path].installHandlers(RED.server);
|
||||
}
|
||||
var node = this;
|
||||
@ -141,7 +142,7 @@ module.exports = function(RED) {
|
||||
client.on('close', function() {
|
||||
delete clients[client.id];
|
||||
node.status({fill:"green",shape:"ring",text:"connected "+Object.keys(clients).length,_sessionid:client.id});
|
||||
node.send({payload:{action:"disconnect", clients:Object.keys(clients).length}, topic:"worldmap", _sessionid:client.id});
|
||||
node.send({payload:{action:"disconnect", clients:Object.keys(clients).length}, topic:node.path.substr(1), _sessionid:client.id});
|
||||
});
|
||||
}
|
||||
|
||||
@ -151,6 +152,7 @@ module.exports = function(RED) {
|
||||
clients[c].end();
|
||||
}
|
||||
}
|
||||
clients = {};
|
||||
sockets[this.path].removeListener('connection', callback);
|
||||
node.status({});
|
||||
});
|
||||
@ -161,8 +163,9 @@ module.exports = function(RED) {
|
||||
|
||||
var WorldMapTracks = function(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.depth = Number(n.depth) || 20;
|
||||
this.depth = parseInt(Number(n.depth) || 20);
|
||||
this.pointsarray = {};
|
||||
this.layer = n.layer || "combined"; // separate, single
|
||||
var node = this;
|
||||
|
||||
node.on("input", function(msg) {
|
||||
@ -174,12 +177,30 @@ module.exports = function(RED) {
|
||||
node.send(newmsg); // send the track to be deleted
|
||||
return;
|
||||
}
|
||||
if (!msg.payload.hasOwnProperty("lat") || !msg.payload.hasOwnProperty("lon")) { return; }
|
||||
if (!node.pointsarray.hasOwnProperty(msg.payload.name)) {
|
||||
node.pointsarray[msg.payload.name] = [];
|
||||
}
|
||||
node.pointsarray[msg.payload.name].push(msg.payload);
|
||||
if (node.pointsarray[msg.payload.name].length > node.depth) {
|
||||
node.pointsarray[msg.payload.name].shift();
|
||||
if (msg.payload.hasOwnProperty("trackpoints") && !isNaN(parseInt(msg.payload.trackpoints)) ) {
|
||||
var tl = parseInt(msg.payload.trackpoints);
|
||||
if (tl < 0) { tl = 0; }
|
||||
if (node.pointsarray[msg.payload.name].length > tl) {
|
||||
node.pointsarray[msg.payload.name] = node.pointsarray[msg.payload.name].slice(-tl);
|
||||
}
|
||||
node.depth = tl;
|
||||
}
|
||||
if (node.depth < 2) { return; } // if set less than 2 then don't bother.
|
||||
|
||||
var still = false;
|
||||
if (node.pointsarray[msg.payload.name].length > 0) {
|
||||
var oldlat = node.pointsarray[msg.payload.name][node.pointsarray[msg.payload.name].length-1].lat;
|
||||
var oldlon = node.pointsarray[msg.payload.name][node.pointsarray[msg.payload.name].length-1].lon;
|
||||
if (msg.payload.lat === oldlat && msg.payload.lon === oldlon) { still = true; }
|
||||
}
|
||||
if (!still) { node.pointsarray[msg.payload.name].push(msg.payload);
|
||||
if (node.pointsarray[msg.payload.name].length > node.depth) {
|
||||
node.pointsarray[msg.payload.name].shift();
|
||||
}
|
||||
}
|
||||
var line = [];
|
||||
for (var i=0; i<node.pointsarray[msg.payload.name].length; i++) {
|
||||
@ -202,6 +223,15 @@ module.exports = function(RED) {
|
||||
if (line.length > 1) { // only send track if two points or more
|
||||
newmsg.payload.line = line;
|
||||
newmsg.payload.name = msg.payload.name + "_";
|
||||
if (node.layer === "separate") {
|
||||
newmsg.payload.layer = msg.payload.layer + " tracks";
|
||||
if (newmsg.payload.layer.indexOf('_') === 0) {
|
||||
newmsg.payload.layer = newmsg.payload.layer.substr(1);
|
||||
}
|
||||
}
|
||||
if (node.layer === "single") {
|
||||
newmsg.payload.layer = "Tracks";
|
||||
}
|
||||
node.send(newmsg); // send the track
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ body {
|
||||
margin:0;
|
||||
padding:0;
|
||||
font:14px Verdana, Arial, sans-serif;
|
||||
overflow:hidden;
|
||||
}
|
||||
|
||||
p, h1, h2, h3, h4 {
|
||||
|
@ -23,6 +23,7 @@
|
||||
<link rel="stylesheet",type="text/css" href="css/map.css"/>
|
||||
<link rel="stylesheet",type="text/css" href="leaflet/leaflet.css"/>
|
||||
<link rel="stylesheet",type="text/css" href="leaflet/font-awesome/css/font-awesome.min.css"/>
|
||||
<link rel="stylesheet",type="text/css" href="leaflet/weather-icons-lite/css/weather-icons-lite.min.css"/>
|
||||
<link rel="stylesheet",type="text/css" href="leaflet/leaflet-vector-markers.css">
|
||||
<link rel="stylesheet",type="text/css" href="leaflet/MarkerCluster.css">
|
||||
<link rel="stylesheet",type="text/css" href="leaflet/MarkerCluster.Default.css">
|
||||
@ -79,7 +80,7 @@
|
||||
<div id="menu"><table>
|
||||
<tr><td><input type='text' name='search' id='search' size='20' style="width:150px;"/> <span onclick='doSearch();'><i class="fa fa-search fa-lg"></i></span></td></tr>
|
||||
<tr><td style="cursor:default"><i class="fa fa-spinner fa-lg fa-fw"></i> Set Max Age <input type='text' name='maxage' id='maxage' value="600" size="5" onchange='setMaxAge();'/>s</td></tr>
|
||||
<tr><td style="cursor:default"><i class="fa fa-search-plus fa-lg fa-fw"></i> Cluster at zoom <<input type='text' name='setclus' id='setclus' size="2" onchange='setCluster();'/></td></tr>
|
||||
<tr><td style="cursor:default"><i class="fa fa-search-plus fa-lg fa-fw"></i> Cluster at zoom <<input type='text' name='setclus' id='setclus' size="2" onchange='setCluster(this.value);'/></td></tr>
|
||||
<tr><td style="cursor:default"><input type='checkbox' id='panit' onclick='doPanit(this.checked);'/> Auto Pan Map</td></tr>
|
||||
<tr><td style="cursor:default"><input type='checkbox' id='lockit' onclick='doLock(this.checked);'/> Lock Map</td></tr>
|
||||
<tr><td style="cursor:default"><input type='checkbox' id='heatall' onclick='doHeatAll(this.checked);'/> Heatmap all layers</td></tr>
|
||||
@ -127,7 +128,7 @@ var buttons = {};
|
||||
var marksIndex = 0;
|
||||
var popid = "";
|
||||
var menuOpen = false;
|
||||
var clusterAt = 13;
|
||||
var clusterAt = 0;
|
||||
var maxage = 600; // default max age of icons on map in seconds - cleared after 10 mins
|
||||
var baselayername = "OSM grey"; // Default base layer OSM but uniform grey
|
||||
var ibmfoot = " © IBM 2015,2019"
|
||||
@ -139,20 +140,20 @@ var sidebyside;
|
||||
var layercontrol;
|
||||
|
||||
var iconSz = {
|
||||
"Team/Crew": 17.5,
|
||||
"Squad": 20,
|
||||
"Section": 22.5,
|
||||
"Platoon/detachment": 25,
|
||||
"Company/battery/troop": 27.5,
|
||||
"Team/Crew": 24,
|
||||
"Squad": 24,
|
||||
"Section": 24,
|
||||
"Platoon/detachment": 26,
|
||||
"Company/battery/troop": 28,
|
||||
"Battalion/squadron": 30,
|
||||
"Regiment/group": 32.5,
|
||||
"Brigade": 35,
|
||||
"Division": 37.5,
|
||||
"Corps/MEF": 40,
|
||||
"Army": 45,
|
||||
"Army Group/front": 50,
|
||||
"Region/Theater": 50,
|
||||
"Command": 50
|
||||
"Regiment/group": 32,
|
||||
"Brigade": 34,
|
||||
"Division": 36,
|
||||
"Corps/MEF": 36,
|
||||
"Army": 40,
|
||||
"Army Group/front": 40,
|
||||
"Region/Theater": 44,
|
||||
"Command": 44
|
||||
};
|
||||
|
||||
// Create the socket
|
||||
@ -704,18 +705,29 @@ var Esri_WorldImagery = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest
|
||||
});
|
||||
basemaps["Esri Satellite"] = Esri_WorldImagery;
|
||||
|
||||
var Esri_WorldShadedRelief = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}', {
|
||||
attribution: 'Tiles © Esri',
|
||||
maxNativeZoom:13
|
||||
var Esri_WorldTopoMap = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}', {
|
||||
attribution: 'Tiles © Esri — Esri, DeLorme, NAVTEQ, TomTom, Intermap, iPC, USGS, FAO, NPS, NRCAN, GeoBase, Kadaster NL, Ordnance Survey, Esri Japan, METI, Esri China (Hong Kong), and the GIS User Community'
|
||||
});
|
||||
basemaps["Esri Terrain"] = Esri_WorldShadedRelief;
|
||||
basemaps["Esri Topography"] = Esri_WorldTopoMap;
|
||||
|
||||
// var Esri_WorldShadedRelief = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}', {
|
||||
// attribution: 'Tiles © Esri',
|
||||
// maxNativeZoom:13
|
||||
// });
|
||||
// basemaps["Esri Terrain"] = Esri_WorldShadedRelief;
|
||||
|
||||
var Esri_OceanBasemap = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/Ocean_Basemap/MapServer/tile/{z}/{y}/{x}', {
|
||||
attribution: 'Tiles © Esri',
|
||||
maxNativeZoom:10
|
||||
attribution: 'Tiles © Esri — Sources: GEBCO, NOAA, CHS, OSU, UNH, CSUMB, National Geographic, DeLorme, NAVTEQ, and Esri',
|
||||
maxZoom: 13
|
||||
});
|
||||
basemaps["Esri Ocean"] = Esri_OceanBasemap;
|
||||
|
||||
var Esri_WorldGrayCanvas = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Base/MapServer/tile/{z}/{y}/{x}', {
|
||||
attribution: 'Tiles © Esri — Esri, DeLorme, NAVTEQ',
|
||||
maxZoom: 16
|
||||
});
|
||||
basemaps["Esri Dark Grey"] = Esri_WorldGrayCanvas;
|
||||
|
||||
// var OpenMapSurfer_Roads = L.tileLayer('https://korona.geog.uni-heidelberg.de/tiles/roads/x={x}&y={y}&z={z}', {
|
||||
// maxZoom: 18,
|
||||
// attribution: 'Imagery from <a href="https://giscience.uni-hd.de/">University of Heidelberg</a> — Map data © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
|
||||
@ -745,12 +757,11 @@ var NLS_OS_opendata = L.tileLayer('https://geo.nls.uk/maps/opendata/{z}/{x}/{y}.
|
||||
});
|
||||
basemaps["UK OS Opendata"] = NLS_OS_opendata;
|
||||
|
||||
// //https://tiles.wmflabs.org/hikebike/{zoom}/{x}/{y}.png
|
||||
// var HikeBike_HikeBike = L.tileLayer('https://tiles.wmflabs.org/hikebike/{z}/{x}/{y}.png', {
|
||||
// maxZoom: 19,
|
||||
// attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
|
||||
// });
|
||||
// basemaps["Hike Bike"] = HikeBike_HikeBike;
|
||||
var HikeBike_HikeBike = L.tileLayer('https://tiles.wmflabs.org/hikebike/{z}/{x}/{y}.png', {
|
||||
maxZoom: 19,
|
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||
});
|
||||
basemaps["Hike Bike"] = HikeBike_HikeBike;
|
||||
|
||||
var NLS_OS_1919_1947 = L.tileLayer( 'https://nls-{s}.tileserver.com/nls/{z}/{x}/{y}.jpg', {
|
||||
attribution: 'Historical Maps Layer, from <a href="https://maps.nls.uk/projects/api/">NLS Maps</a>',
|
||||
@ -935,7 +946,7 @@ function setMarker(data) {
|
||||
delMarker(data.name);
|
||||
return;
|
||||
}
|
||||
data = allData[data.name] = Object.assign(allData[data.name] || {}, data);
|
||||
|
||||
var ll;
|
||||
var lli = null;
|
||||
var opt = {};
|
||||
@ -962,30 +973,46 @@ function setMarker(data) {
|
||||
map.addLayer(layers["buildings"]);
|
||||
return;
|
||||
}
|
||||
|
||||
var lay = data.layer || "unknown";
|
||||
if (typeof layers[lay] == "undefined") { // add layer if if doesn't exist
|
||||
if (clusterAt > 0) {
|
||||
layers[lay] = new L.MarkerClusterGroup({
|
||||
maxClusterRadius:50,
|
||||
spiderfyDistanceMultiplier:1.8,
|
||||
disableClusteringAtZoom:clusterAt
|
||||
//zoomToBoundsOnClick:false
|
||||
});
|
||||
if (!data.hasOwnProperty("action") || data.action.indexOf("layer") === -1) {
|
||||
if (typeof layers[lay] == "undefined") { // add layer if if doesn't exist
|
||||
if (clusterAt > 0) {
|
||||
layers[lay] = new L.MarkerClusterGroup({
|
||||
maxClusterRadius:50,
|
||||
spiderfyDistanceMultiplier:1.8,
|
||||
disableClusteringAtZoom:clusterAt
|
||||
//zoomToBoundsOnClick:false
|
||||
});
|
||||
}
|
||||
else {
|
||||
layers[lay] = new L.LayerGroup();
|
||||
}
|
||||
overlays[lay] = layers[lay];
|
||||
if (showLayerMenu !== false) {
|
||||
layercontrol.addOverlay(layers[lay],lay);
|
||||
}
|
||||
map.addLayer(overlays[lay]);
|
||||
//console.log("ADDED LAYER",lay,layers);
|
||||
}
|
||||
else {
|
||||
layers[lay] = new L.LayerGroup();
|
||||
}
|
||||
overlays[lay] = layers[lay];
|
||||
if (showLayerMenu !== false) {
|
||||
layercontrol.addOverlay(layers[lay],lay);
|
||||
}
|
||||
map.addLayer(overlays[lay]);
|
||||
//console.log("ADDED LAYER",lay,layers);
|
||||
if (!allData.hasOwnProperty(data.name)) { allData[data.name] = {}; }
|
||||
delete data.action;
|
||||
Object.keys(data).forEach(key => {
|
||||
if (data[key] == null) { delete allData[data.name][key]; }
|
||||
else { allData[data.name][key] = data[key]; }
|
||||
});
|
||||
data = Object.assign({},allData[data.name]);
|
||||
}
|
||||
delete data.action;
|
||||
|
||||
if (typeof markers[data.name] != "undefined") {
|
||||
try {layers[lay].removeLayer(markers[data.name]); }
|
||||
catch(e) { console.log("OOPS"); }
|
||||
if (markers[data.name].lay !== data.layer) {
|
||||
delMarker(data.name);
|
||||
}
|
||||
else {
|
||||
try {layers[lay].removeLayer(markers[data.name]); }
|
||||
catch(e) { console.log("OOPS"); }
|
||||
}
|
||||
}
|
||||
if (typeof polygons[data.name] != "undefined") { layers[lay].removeLayer(polygons[data.name]); }
|
||||
|
||||
@ -1033,7 +1060,6 @@ function setMarker(data) {
|
||||
layers[lay].addLayer(polycirc);
|
||||
}
|
||||
}
|
||||
//console.log("handling",data.name);
|
||||
if (typeof data.coordinates == "object") { ll = new L.LatLng(data.coordinates[1],data.coordinates[0]); }
|
||||
else if (data.hasOwnProperty("position") && data.position.hasOwnProperty("lat") && data.position.hasOwnProperty("lon")) {
|
||||
data.lat = data.position.lat*1;
|
||||
@ -1053,8 +1079,6 @@ function setMarker(data) {
|
||||
else if (data.hasOwnProperty("latitude") && data.hasOwnProperty("longitude") && data.hasOwnProperty("intensity")) { lli = new L.LatLng((data.latitude*1), (data.longitude*1), (data.intensity*1)); }
|
||||
else { lli = ll }
|
||||
|
||||
var words="";
|
||||
|
||||
// Create the icons... handle plane, car, ship, wind, earthquake as specials
|
||||
var marker, myMarker;
|
||||
var icon, q;
|
||||
@ -1258,6 +1282,19 @@ function setMarker(data) {
|
||||
marker = L.marker(ll, {title:data.name, icon:myMarker, draggable:drag});
|
||||
labelOffset = [8,-8];
|
||||
}
|
||||
else if (data.icon && (data.icon.substr(0,3) === "wi-")) {
|
||||
var col = data.iconColor || "#910000";
|
||||
var imod = "";
|
||||
if (data.icon.indexOf(" ") === -1) { imod = "wi-2x "; }
|
||||
myMarker = L.divIcon({
|
||||
className:"wiicon",
|
||||
html: '<center><i class="wi wi-fw '+imod+data.icon+'" style="color:'+col+'"></i></center>',
|
||||
iconSize: [32, 32],
|
||||
popupAnchor: [0, -16]
|
||||
});
|
||||
marker = L.marker(ll, {title:data.name, icon:myMarker, draggable:drag});
|
||||
labelOffset = [16,-16];
|
||||
}
|
||||
else {
|
||||
myMarker = L.VectorMarkers.icon({
|
||||
icon: data.icon || "circle",
|
||||
@ -1300,7 +1337,7 @@ function setMarker(data) {
|
||||
delete data.photoUrl;
|
||||
}
|
||||
if (data.hasOwnProperty("videoUrl")) {
|
||||
words += '<video controls autoplay><source src="'+data.videoUrl+'" type="video/mp4">Your browser does not support the video tag.</video>';
|
||||
words += '<video controls muted autoplay width="320"><source src="'+data.videoUrl+'" type="video/mp4">Your browser does not support the video tag.</video>';
|
||||
delete data.videoUrl;
|
||||
}
|
||||
if (data.hasOwnProperty("ttl")) { // save expiry time for this marker
|
||||
@ -1340,6 +1377,12 @@ function setMarker(data) {
|
||||
delete data.tooltip;
|
||||
}
|
||||
}
|
||||
// customise right click context menu
|
||||
var rightcontext = "<button id='delbutton' onclick='delMarker(\""+data.name+"\",true);'>Delete</button>";
|
||||
if ((data.contextmenu !== undefined) && (typeof data.contextmenu === "string")) {
|
||||
rightcontext = data.contextmenu.replace(/$name/g,'\""+'+data.name+'+"\"');
|
||||
delete data.contextmenu;
|
||||
}
|
||||
|
||||
// Add any remaining properties to the info box
|
||||
var llc = data.lineColor;
|
||||
@ -1347,6 +1390,11 @@ function setMarker(data) {
|
||||
delete data.lon;
|
||||
if (data.layer) { delete data.layer; }
|
||||
if (data.lineColor) { delete data.lineColor; }
|
||||
if (data.color) { delete data.color; }
|
||||
if (data.weight) { delete data.weight; }
|
||||
if (data.tracklength) { delete data.tracklength; }
|
||||
if (data.dashArray) { delete data.dashArray; }
|
||||
if (data.fill) { delete data.fill; }
|
||||
if (data.draggable) { delete data.draggable; }
|
||||
for (var i in data) {
|
||||
if ((i != "name") && (i != "length")) {
|
||||
|
@ -17,7 +17,7 @@ JSON.parse(a)}catch(d){}c(b)})}}}(),F={loadedItems:{},items:[],getPixelFootprint
|
||||
(c[k]=1,m.push(d),l.push(k),m.push(k),l.push(f));d=m.pop();f=l.pop()}for(e=0;e<a;e++)c[e]&&n.push(b[2*e],b[2*e+1]);a=n;if(!(8>a.length))return a},resetItems:function(){this.items=[];this.loadedItems={};Y.reset()},addRenderItems:function(b,a){for(var c,d,f,e=Ja.read(b),g=0,h=e.length;g<h;g++)c=e[g],f=c.id||[c.footprint[0],c.footprint[1],c.height,c.minHeight].join(),!this.loadedItems[f]&&(d=this.scale(c))&&(d.scale=a?0:1,this.items.push(d),this.loadedItems[f]=1);Ca()},scale:function(b){var a={},c=6/
|
||||
oa(2,x-G);b.id&&(a.id=b.id);a.height=U(b.height/c,ga);a.minHeight=isNaN(b.minHeight)?0:b.minHeight/c;if(!(a.minHeight>ga)&&(a.footprint=this.getPixelFootprint(b.footprint),a.footprint)){for(var d=a.footprint,f=Infinity,e=-Infinity,g=Infinity,h=-Infinity,k=0,m=d.length-3;k<m;k+=2)f=U(f,d[k]),e=K(e,d[k]),g=U(g,d[k+1]),h=K(h,d[k+1]);a.center={x:f+(e-f)/2<<0,y:g+(h-g)/2<<0};b.radius&&(a.radius=b.radius*na);b.shape&&(a.shape=b.shape);b.roofShape&&(a.roofShape=b.roofShape);"cone"!==a.roofShape&&"dome"!==
|
||||
a.roofShape||a.shape||!va(a.footprint)||(a.shape="cylinder");if(b.holes){a.holes=[];for(var l,d=0,f=b.holes.length;d<f;d++)(l=this.getPixelFootprint(b.holes[d]))&&a.holes.push(l)}var n;b.wallColor&&(n=I.parse(b.wallColor))&&(n=n.alpha(C),a.altColor=""+n.lightness(0.8),a.wallColor=""+n);b.roofColor&&(n=I.parse(b.roofColor))&&(a.roofColor=""+n.alpha(C));b.relationId&&(a.relationId=b.relationId);a.hitColor=Y.idToColor(b.relationId||b.id);a.roofHeight=isNaN(b.roofHeight)?0:b.roofHeight/c;if(!(a.height+
|
||||
a.roofHeight<=a.minHeight))return a}},set:function(b){this.isStatic=!0;this.resetItems();this._staticData=b;this.addRenderItems(this._staticData,!0)},load:function(b,a){this.src=b||"http://{s}.data.osmbuildings.org/0.2/{k}/tile/{z}/{x}/{y}.json".replace("{k}",a||"anonymous");this.update()},update:function(){function b(a){g.addRenderItems(a)}this.resetItems();if(!(x<G))if(this.isStatic&&this._staticData)this.addRenderItems(this._staticData);else if(this.src){var a=16<x?256<<x-16:256>>16-x,c=p/a<<0,
|
||||
a.roofHeight<=a.minHeight))return a}},set:function(b){this.isStatic=!0;this.resetItems();this._staticData=b;this.addRenderItems(this._staticData,!0)},load:function(b,a){this.src=b||"https://{s}.data.osmbuildings.org/0.2/{k}/tile/{z}/{x}/{y}.json".replace("{k}",a||"anonymous");this.update()},update:function(){function b(a){g.addRenderItems(a)}this.resetItems();if(!(x<G))if(this.isStatic&&this._staticData)this.addRenderItems(this._staticData);else if(this.src){var a=16<x?256<<x-16:256>>16-x,c=p/a<<0,
|
||||
d=n/a<<0,f=qa((p+B)/a),a=qa((n+v)/a),e,g=this;for(e=d;e<=a;e++)for(d=c;d<=f;d++)this.loadTile(d,e,16,b)}},loadTile:function(b,a,c,d){b=this.src.replace("{s}","abcd"[(b+a)%4]).replace("{x}",b).replace("{y}",a).replace("{z}",c);return Ka.loadJSON(b,d)}},Z={draw:function(b,a,c,d,f,e,g,h){var k,m=this._extrude(b,a,d,f,e,g),l=[];if(c)for(a=0,k=c.length;a<k;a++)l[a]=this._extrude(b,c[a],d,f,e,g);b.fillStyle=h;b.beginPath();this._ring(b,m);if(c)for(a=0,k=l.length;a<k;a++)this._ring(b,l[a]);b.closePath();
|
||||
b.stroke();b.fill()},_extrude:function(b,a,c,d,f,e){c=q/(q-c);for(var g=q/(q-d),h={x:0,y:0},k={x:0,y:0},m,l,y=[],s=0,t=a.length-3;s<t;s+=2)h.x=a[s]-p,h.y=a[s+1]-n,k.x=a[s+2]-p,k.y=a[s+3]-n,m=r.project(h,c),l=r.project(k,c),d&&(h=r.project(h,g),k=r.project(k,g)),(k.x-h.x)*(m.y-h.y)>(m.x-h.x)*(k.y-h.y)&&(b.fillStyle=h.x<k.x&&h.y<k.y||h.x>k.x&&h.y>k.y?e:f,b.beginPath(),this._ring(b,[k.x,k.y,h.x,h.y,m.x,m.y,l.x,l.y]),b.closePath(),b.fill()),y[s]=m.x,y[s+1]=m.y;return y},_ring:function(b,a){b.moveTo(a[0],
|
||||
a[1]);for(var c=2,d=a.length-1;c<d;c+=2)b.lineTo(a[c],a[c+1])},simplified:function(b,a,c){b.beginPath();this._ringAbs(b,a);if(c){a=0;for(var d=c.length;a<d;a++)this._ringAbs(b,c[a])}b.closePath();b.stroke();b.fill()},_ringAbs:function(b,a){b.moveTo(a[0]-p,a[1]-n);for(var c=2,d=a.length-1;c<d;c+=2)b.lineTo(a[c]-p,a[c+1]-n)},shadow:function(b,a,c,d,f){for(var e=null,g={x:0,y:0},h={x:0,y:0},k,m,l=0,q=a.length-3;l<q;l+=2)g.x=a[l]-p,g.y=a[l+1]-n,h.x=a[l+2]-p,h.y=a[l+3]-n,k=z.project(g,d),m=z.project(h,
|
||||
@ -41,8 +41,8 @@ case "dome":w.hitArea(b,a.center,a.radius,a.radius/2,c+a.roofHeight,c,g);break;c
|
||||
$,A={container:document.createElement("DIV"),items:[],init:function(){this.container.style.pointerEvents="none";this.container.style.position="absolute";this.container.style.left=0;this.container.style.top=0;z.context=this.createContext(this.container);ia.context=this.createContext(this.container);r.context=this.createContext(this.container);Y.context=this.createContext()},render:function(b){Ga(function(){b||(z.render(),ia.render(),Y.render());r.render()})},createContext:function(b){var a=document.createElement("CANVAS");
|
||||
a.style.transform="translate3d(0, 0, 0)";a.style.imageRendering="optimizeSpeed";a.style.position="absolute";a.style.left=0;a.style.top=0;var c=a.getContext("2d");c.lineCap="round";c.lineJoin="round";c.lineWidth=1;c.imageSmoothingEnabled=!1;this.items.push(a);b&&b.appendChild(a);return c},appendTo:function(b){b.appendChild(this.container)},remove:function(){this.container.parentNode.removeChild(this.container)},setSize:function(b,a){for(var c=0,d=this.items.length;c<d;c++)this.items[c].width=b,this.items[c].height=
|
||||
a},setPosition:function(b,a){this.container.style.left=b+"px";this.container.style.top=a+"px"}};A.init();u=function(b){this.offset={x:0,y:0};b&&b.addLayer(this)};t=u.prototype=L.Layer?new L.Layer:{};t.addTo=function(b){b.addLayer(this);return this};t.onAdd=function(b){this.map=b;A.appendTo(b._panes.overlayPane);var a=this.getOffset(),c=b.getPixelOrigin();la({width:b._size.x,height:b._size.y});var d=c.y-a.y;p=c.x-a.x;n=d;ma(b._zoom);A.setPosition(-a.x,-a.y);b.on({move:this.onMove,moveend:this.onMoveEnd,
|
||||
zoomstart:this.onZoomStart,zoomend:this.onZoomEnd,resize:this.onResize,viewreset:this.onViewReset,click:this.onClick},this);if(b.options.zoomAnimation)b.on("zoomanim",this.onZoom,this);b.attributionControl&&b.attributionControl.addAttribution('© <a href="http://osmbuildings.org">OSM Buildings</a>');F.update()};t.onRemove=function(){var b=this.map;b.attributionControl&&b.attributionControl.removeAttribution('© <a href="http://osmbuildings.org">OSM Buildings</a>');b.off({move:this.onMove,
|
||||
zoomstart:this.onZoomStart,zoomend:this.onZoomEnd,resize:this.onResize,viewreset:this.onViewReset,click:this.onClick},this);if(b.options.zoomAnimation)b.on("zoomanim",this.onZoom,this);b.attributionControl&&b.attributionControl.addAttribution('© <a href="https://osmbuildings.org">OSM Buildings</a>');F.update()};t.onRemove=function(){var b=this.map;b.attributionControl&&b.attributionControl.removeAttribution('© <a href="https://osmbuildings.org">OSM Buildings</a>');b.off({move:this.onMove,
|
||||
moveend:this.onMoveEnd,zoomstart:this.onZoomStart,zoomend:this.onZoomEnd,resize:this.onResize,viewreset:this.onViewReset,click:this.onClick},this);b.options.zoomAnimation&&b.off("zoomanim",this.onZoom,this);A.remove()};t.onMove=function(b){b=this.getOffset();ea({x:this.offset.x-b.x,y:this.offset.y-b.y})};t.onMoveEnd=function(b){if(this.noMoveEnd)this.noMoveEnd=!1;else{var a=this.map;b=this.getOffset();var c=a.getPixelOrigin();this.offset=b;A.setPosition(-b.x,-b.y);ea({x:0,y:0});la({width:a._size.x,
|
||||
height:a._size.y});a=c.y-b.y;p=c.x-b.x;n=a;A.render();F.update()}};t.onZoomStart=function(b){Q=!0;A.render()};t.onZoom=function(b){};t.onZoomEnd=function(b){b=this.map;var a=this.getOffset(),c=b.getPixelOrigin(),d=c.y-a.y;p=c.x-a.x;n=d;b=b._zoom;Q=!1;ma(b);F.update();A.render();this.noMoveEnd=!0};t.onResize=function(){};t.onViewReset=function(){var b=this.getOffset();this.offset=b;A.setPosition(-b.x,-b.y);ea({x:0,y:0})};t.onClick=function(b){var a=Y.getIdFromXY(b.containerPoint.x,b.containerPoint.y);
|
||||
a&&ua({feature:a,lat:b.latlng.lat,lon:b.latlng.lng})};t.getOffset=function(){return L.DomUtil.getPosition(this.map._mapPane)};t.style=function(b){b=b||{};var a;if(a=b.color||b.wallColor)H=I.parse(a),ha=""+H.alpha(C),ba=H.lightness(0.8),aa=""+ba.alpha(C),O=H.lightness(1.2),X=""+O.alpha(C);b.roofColor&&(O=I.parse(b.roofColor),X=""+O.alpha(C));void 0!==b.shadows&&(z.enabled=!!b.shadows);A.render();return this};t.date=function(b){z.date=b;z.render();return this};t.load=function(b){F.load(b);return this};
|
||||
t.set=function(b){F.set(b);return this};var ta=function(){};t.each=function(b){ta=function(a){return b(a)};return this};var ua=function(){};t.click=function(b){ua=function(a){return b(a)};return this};u.VERSION="0.2.2b";u.ATTRIBUTION='© <a href="http://osmbuildings.org">OSM Buildings</a>';ca.OSMBuildings=u})(this);
|
||||
t.set=function(b){F.set(b);return this};var ta=function(){};t.each=function(b){ta=function(a){return b(a)};return this};var ua=function(){};t.click=function(b){ua=function(a){return b(a)};return this};u.VERSION="0.2.2b";u.ATTRIBUTION='© <a href="https://osmbuildings.org">OSM Buildings</a>';ca.OSMBuildings=u})(this);
|
||||
|
@ -35,8 +35,9 @@ L.TileLayer.GrayWMS = L.TileLayer.WMS.extend({
|
||||
var imgd = ctx.getImageData(0, 0, this._layer.options.tileSize, this._layer.options.tileSize);
|
||||
var pix = imgd.data;
|
||||
for (var i = 0, n = pix.length; i < n; i += 4) {
|
||||
pix[i] = pix[i + 1] = pix[i + 2] = (3 * pix[i] + 4 * pix[i + 1] + pix[i + 2]) / 8;
|
||||
//pix[i] = pix[i + 1] = pix[i + 2] = (2 * pix[i] + 3 * pix[i + 1] + 3 * pix[i + 2]) / 6;
|
||||
//pix[i] = pix[i + 1] = pix[i + 2] = (3 * pix[i] + 4 * pix[i + 1] + pix[i + 2]) / 8;
|
||||
// Lighten the scale slightly to make markers more obvious
|
||||
pix[i] = pix[i + 1] = pix[i + 2] = (3 * pix[i] + 4 * pix[i + 1] + pix[i + 2]) / 8 * 3 / 4 + 64;
|
||||
}
|
||||
ctx.putImageData(imgd, 0, 0);
|
||||
this.removeAttribute("crossorigin");
|
||||
|
9
worldmap/leaflet/weather-icons-lite/css/weather-icons-lite.min.css
vendored
Executable file
9
worldmap/leaflet/weather-icons-lite/css/weather-icons-lite.min.css
vendored
Executable file
@ -0,0 +1,9 @@
|
||||
/*!
|
||||
* Weather Icons Lite
|
||||
* Weather themed icons for Bootstrap
|
||||
* Author - Paul Reed
|
||||
* Maintained at https://github.com/Paul-Reed/weather-icons-lite
|
||||
* Description - A lighweight version of Weather Icons
|
||||
* Credit to Erik Flowers - erik@helloerik.com
|
||||
*
|
||||
*/@font-face{font-family:'weather-icons-lite';font-weight:normal;font-style:normal;src:url('../fonts/weather-icons-lite.woff2') format('woff2'),url('../fonts/weather-icons-lite.woff') format('woff'),url('../fonts/weather-icons-lite.ttf') format('truetype'),url('../fonts/weather-icons-lite.eot') format('embedded-opentype')}.wi{display:inline-block;font-family:'weather-icons-lite';font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.wi-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.wi-xs{font-size:.75em}.wi-sm{font-size:.875em}.wi-1x{font-size:1em}.wi-2x{font-size:2em}.wi-3x{font-size:3em}.wi-4x{font-size:4em}.wi-5x{font-size:5em}.wi-6x{font-size:6em}.wi-7x{font-size:7em}.wi-8x{font-size:8em}.wi-9x{font-size:9em}.wi-10x{font-size:10em}.wi-fw{text-align:center;width:1.4em}.wi-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.wi-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.wi-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.wi-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0,mirror=1);-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.wi-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2,mirror=1);-webkit-transform:scale(1,-1);-ms-transform:scale(1,-1);transform:scale(1,-1)}.wi-darksky-clear-day:before{content:"\f00d"}.wi-darksky-clear-night:before{content:"\f02e"}.wi-darksky-rain:before{content:"\f019"}.wi-darksky-snow:before{content:"\f01b"}.wi-darksky-sleet:before{content:"\f0b5"}.wi-darksky-wind:before{content:"\f050"}.wi-darksky-fog:before{content:"\f014"}.wi-darksky-cloudy:before{content:"\f013"}.wi-darksky-partly-cloudy-day:before{content:"\f002"}.wi-darksky-partly-cloudy-night:before{content:"\f086"}.wi-darksky-hail:before{content:"\f015"}.wi-darksky-thunderstorm:before{content:"\f01e"}.wi-darksky-tornado:before{content:"\f056"}.wi-owm-01d:before{content:"\f00d"}.wi-owm-02d:before{content:"\f00c"}.wi-owm-03d:before{content:"\f002"}.wi-owm-04d:before{content:"\f013"}.wi-owm-09d:before{content:"\f017"}.wi-owm-10d:before{content:"\f019"}.wi-owm-11d:before{content:"\f01e"}.wi-owm-13d:before{content:"\f01b"}.wi-owm-50d:before{content:"\f014"}.wi-owm-01n:before{content:"\f02e"}.wi-owm-02n:before{content:"\f081"}.wi-owm-03n:before{content:"\f07e"}.wi-owm-04n:before{content:"\f086"}.wi-owm-09n:before{content:"\f026"}.wi-owm-10n:before{content:"\f028"}.wi-owm-11n:before{content:"\f02c"}.wi-owm-13n:before{content:"\f02a"}.wi-owm-50n:before{content:"\f04a"}.wi-wu-chanceflurries:before{content:"\f064"}.wi-wu-chancerain:before{content:"\f019"}.wi-wu-chancesleet:before{content:"\f0b5"}.wi-wu-chancesnow:before{content:"\f01b"}.wi-wu-chancetstorms:before{content:"\f01e"}.wi-wu-clear:before{content:"\f00d"}.wi-wu-cloudy:before{content:"\f002"}.wi-wu-flurries:before{content:"\f064"}.wi-wu-fog:before{content:"\f014"}.wi-wu-hazy:before{content:"\f0b6"}.wi-wu-mostlycloudy:before{content:"\f002"}.wi-wu-mostlysunny:before{content:"\f00d"}.wi-wu-partlycloudy:before{content:"\f002"}.wi-wu-partlysunny:before{content:"\f00d"}.wi-wu-rain:before{content:"\f01a"}.wi-wu-sleet:before{content:"\f0b5"}.wi-wu-snow:before{content:"\f01b"}.wi-wu-sunny:before{content:"\f00d"}.wi-wu-tstorms:before{content:"\f01e"}.wi-wu-nt_chanceflurries:before{content:"\f067"}.wi-wu-nt_chancerain:before{content:"\f028"}.wi-wu-nt_chancesleet:before{content:"\f0b4"}.wi-wu-nt_chancesnow:before{content:"\f02a"}.wi-wu-nt_chancetstorms:before{content:"\f02d"}.wi-wu-nt_clear:before{content:"\f02e"}.wi-wu-nt_flurries:before{content:"\f067"}.wi-wu-nt_fog:before{content:"\f04a"}.wi-wu-nt_hazy:before{content:"\f07e"}.wi-wu-nt_mostlycloudy:before{content:"\f081"}.wi-wu-nt_mostlysunny:before{content:"\f02e"}.wi-wu-nt_partlycloudy:before{content:"\f081"}.wi-wu-nt_partlysunny:before{content:"\f086"}.wi-wu-nt_rain:before{content:"\f028"}.wi-wu-nt_sleet:before{content:"\f0b4"}.wi-wu-nt_snow:before{content:"\f02a"}.wi-wu-nt_sunny:before{content:"\f02e"}.wi-wu-nt_tstorms:before{content:"\f02d"}.wi-wu-nt_cloudy:before{content:"\f031"}
|
BIN
worldmap/leaflet/weather-icons-lite/fonts/weather-icons-lite.woff
Executable file
BIN
worldmap/leaflet/weather-icons-lite/fonts/weather-icons-lite.woff
Executable file
Binary file not shown.
BIN
worldmap/leaflet/weather-icons-lite/fonts/weather-icons-lite.woff2
Executable file
BIN
worldmap/leaflet/weather-icons-lite/fonts/weather-icons-lite.woff2
Executable file
Binary file not shown.
Loading…
Reference in New Issue
Block a user