diff --git a/README.md b/README.md index 3249b73..9107a2a 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ A web-app to visualize nodes and links on a map for Freifunk open mesh network. #### Main differences to https://github.com/ffnord/meshviewer _Some similar features might have been implemented/merged_ +- Leaflet upgraded to v1 - faster on mobile - Forcegraph rewrite with d3.js v4 - Map layer modes (Allow to set a default layer based on time combined with a stylesheet) - Automatic updates for selected node or list (incl. image stats cache-breaker) @@ -23,13 +24,12 @@ _Some similar features might have been implemented/merged_ - css and some js moved inline - Yarn/npm in favour of bower - Load only moment.js without languages (Languages are included in translations) - - unneeded components removed (es6-shim, tablesort, numeraljs, leaflet-providers, jshashes, chroma-js) + - unneeded components removed (es6-shim, tablesort, numeraljs, leaflet-providers, leaflet-label jshashes, chroma-js) - RBush v2 - performance boost in last versions (positions, labels and clients on the map) - Ruby dependency removed - FixedCenter is required - Sass-lint, scss and variables rewritten for easy customizations/adjustments - Cross browser/device support improved (THX@BrowserStack) -- Leaflet fork with a patch to avoid IE/Edge crashes - Yarn package manager in favour of npm (npm still works) - Configurable reverse geocoding server - [A lot more in the commit history](https://github.com/ffrgb/meshviewer/commits/develop) diff --git a/app.js b/app.js index 9e2f0b7..5bc3e5a 100644 --- a/app.js +++ b/app.js @@ -58,7 +58,6 @@ require.config({ paths: { 'polyglot': '../node_modules/node-polyglot/build/polyglot', 'leaflet': '../node_modules/leaflet/dist/leaflet', - 'leaflet.label': '../node_modules/leaflet-label/dist/leaflet.label', 'moment': '../node_modules/moment/moment', // d3 modules indirect dependencies // by d3-zoom: d3-drag @@ -83,7 +82,6 @@ require.config({ 'language': 'utils/language' }, shim: { - 'leaflet.label': ['leaflet'], 'd3-drag': ['d3-selection'], 'd3-force': ['d3-collection', 'd3-dispatch', 'd3-quadtree', 'd3-timer'], 'd3-interpolate': ['d3-color'], diff --git a/lib/map.js b/lib/map.js index 56f2803..20a1a5e 100644 --- a/lib/map.js +++ b/lib/map.js @@ -1,10 +1,11 @@ -define(['map/clientlayer', 'map/labelslayer', 'leaflet', 'moment', 'locationmarker', 'rbush', 'helper'], - function (ClientLayer, LabelsLayer, L, moment, LocationMarker, rbush, helper) { +define(['map/clientlayer', 'map/labellayer', 'leaflet', 'moment', 'map/locationmarker', 'rbush', 'helper'], + function (ClientLayer, LabelLayer, L, moment, LocationMarker, rbush, helper) { 'use strict'; var options = { worldCopyJump: true, - zoomControl: true + zoomControl: true, + minZoom: 0 }; var ButtonBase = L.Control.extend({ @@ -296,18 +297,23 @@ define(['map/clientlayer', 'map/labelslayer', 'leaflet', 'moment', 'locationmark map.zoomControl.setPosition('topright'); - var clientLayer = new ClientLayer('', { minZoom: config.clientZoom }); + var clientLayer = new ClientLayer({ minZoom: config.clientZoom }); clientLayer.addTo(map); clientLayer.setZIndex(5); - var labelsLayer = new LabelsLayer('', { minZoom: config.labelZoom }); - labelsLayer.addTo(map); - labelsLayer.setZIndex(6); + var labelLayer = new LabelLayer({ minZoom: config.labelZoom }); + labelLayer.addTo(map); + labelLayer.setZIndex(6); + + map.on('zoom', function () { + clientLayer.redraw(); + labelLayer.redraw(); + }); map.on('baselayerchange', function (e) { map.options.maxZoom = e.layer.options.maxZoom; clientLayer.options.maxZoom = map.options.maxZoom; - labelsLayer.options.maxZoom = map.options.maxZoom; + labelLayer.options.maxZoom = map.options.maxZoom; if (map.getZoom() > map.options.maxZoom) { map.setZoom(map.options.maxZoom); } @@ -315,13 +321,13 @@ define(['map/clientlayer', 'map/labelslayer', 'leaflet', 'moment', 'locationmark var style = document.querySelector('.css-mode:not([media="not"])'); if (style && e.layer.options.mode !== '' && !style.classList.contains(e.layer.options.mode)) { style.media = 'not'; - labelsLayer.updateLayer(); + labelLayer.updateLayer(); } if (e.layer.options.mode) { var newStyle = document.querySelector('.css-mode.' + e.layer.options.mode); newStyle.media = ''; newStyle.appendChild(document.createTextNode('')); - labelsLayer.updateLayer(); + labelLayer.updateLayer(); } }); @@ -457,7 +463,7 @@ define(['map/clientlayer', 'map/labelslayer', 'leaflet', 'moment', 'locationmark rtreeOnlineAll.load(data.nodes.all.filter(helper.online).filter(helper.hasLocation).map(mapRTree)); clientLayer.setData(rtreeOnlineAll); - labelsLayer.setData({ + labelLayer.setData({ online: nodesOnline.filter(helper.hasLocation), offline: nodesOffline.filter(helper.hasLocation), new: data.nodes.new.filter(helper.hasLocation), diff --git a/lib/map/clientlayer.js b/lib/map/clientlayer.js index 2aa2a5c..06d1432 100644 --- a/lib/map/clientlayer.js +++ b/lib/map/clientlayer.js @@ -2,7 +2,7 @@ define(['leaflet', 'helper'], function (L, helper) { 'use strict'; - return L.TileLayer.extend({ + return L.GridLayer.extend({ setData: function (d) { this.data = d; @@ -12,12 +12,18 @@ define(['leaflet', 'helper'], }); this.redraw(); }, - drawTile: function (canvas, tilePoint) { - if (!this.data) { - return; - } + createTile: function (tilePoint) { + var tile = L.DomUtil.create('canvas', 'leaflet-tile'); var tileSize = this.options.tileSize; + tile.width = tileSize; + tile.height = tileSize; + + if (!this.data) { + return tile; + } + + var ctx = tile.getContext('2d'); var s = tilePoint.multiplyBy(tileSize); var map = this._map; @@ -27,10 +33,9 @@ define(['leaflet', 'helper'], var nodes = this.data.search(bbox); if (nodes.length === 0) { - return; + return tile; } - var ctx = canvas.getContext('2d'); var startDistance = 12; ctx.beginPath(); @@ -45,6 +50,8 @@ define(['leaflet', 'helper'], ctx.fillStyle = 'rgba(220, 0, 103, 0.7)'; ctx.fill(); + + return tile; } }); }); diff --git a/lib/map/labelslayer.js b/lib/map/labellayer.js similarity index 94% rename from lib/map/labelslayer.js rename to lib/map/labellayer.js index 12bea03..e136826 100644 --- a/lib/map/labelslayer.js +++ b/lib/map/labellayer.js @@ -70,9 +70,9 @@ define(['leaflet', 'rbush', 'helper'], return { minX: x, minY: y, maxX: x + width, maxY: y + height }; } - return L.TileLayer.extend({ + return L.GridLayer.extend({ onAdd: function (map) { - L.TileLayer.prototype.onAdd.call(this, map); + L.GridLayer.prototype.onAdd.call(this, map); if (this.data) { this.prepareLabels(); } @@ -180,12 +180,17 @@ define(['leaflet', 'rbush', 'helper'], this.redraw(); }, - drawTile: function (canvas, tilePoint, zoom) { - if (!this.labels && zoom >= this.options.minZoom) { - return; - } + createTile: function (tilePoint) { + var tile = L.DomUtil.create('canvas', 'leaflet-tile'); var tileSize = this.options.tileSize; + tile.width = tileSize; + tile.height = tileSize; + + if (!this.labels) { + return tile; + } + var s = tilePoint.multiplyBy(tileSize); var map = this._map; bodyStyle = window.getComputedStyle(document.querySelector('body')); @@ -202,7 +207,7 @@ define(['leaflet', 'rbush', 'helper'], var bbox = helper.getTileBBox(s, map, tileSize, this.margin); var labels = this.labels.search(bbox).map(projectNodes); - var ctx = canvas.getContext('2d'); + var ctx = tile.getContext('2d'); ctx.lineWidth = 5; ctx.strokeStyle = labelShadow; @@ -222,8 +227,10 @@ define(['leaflet', 'rbush', 'helper'], } labels.filter(function (d) { - return zoom >= d.label.minZoom; + return tilePoint.z >= d.label.minZoom; }).forEach(drawLabel); + + return tile; } }); }); diff --git a/lib/locationmarker.js b/lib/map/locationmarker.js similarity index 100% rename from lib/locationmarker.js rename to lib/map/locationmarker.js