diff options
| author | Adam Harvey <adam@ahprojects.com> | 2018-12-23 01:37:03 +0100 |
|---|---|---|
| committer | Adam Harvey <adam@ahprojects.com> | 2018-12-23 01:37:03 +0100 |
| commit | 4452e02e8b04f3476273574a875bb60cfbb4568b (patch) | |
| tree | 3ffa44f9621b736250a8b94da14a187dc785c2fe /client/map | |
| parent | 2a65f7a157bd4bace970cef73529867b0e0a374d (diff) | |
| parent | 5340bee951c18910fd764241945f1f136b5a22b4 (diff) | |
.
Diffstat (limited to 'client/map')
| -rw-r--r-- | client/map/index.js | 78 | ||||
| -rw-r--r-- | client/map/leaflet.bezier.js | 261 |
2 files changed, 339 insertions, 0 deletions
diff --git a/client/map/index.js b/client/map/index.js new file mode 100644 index 00000000..053cf13b --- /dev/null +++ b/client/map/index.js @@ -0,0 +1,78 @@ +import L from 'leaflet' +import './leaflet.bezier' + +function getCitations(dataset) { + // console.log(dataset.citations) + return dataset.citations.map(c => ({ + title: c[0], + location: c[2], + lat: c[5], + lng: c[6], + type: c[7], + })) +} + +const arcStyle = { + color: 'rgb(245, 246, 150)', + fillColor: 'rgb(245, 246, 150)', + opacity: 0.8, + weight: '1', +} + +const redDot = L.icon({ + iconUrl: '/assets/img/reddot.png', + iconSize: [17, 17], // size of the icon + iconAnchor: [8, 8], // point of the icon which will correspond to marker's location + popupAnchor: [0, -5] // point from which the popup should open relative to the iconAnchor +}) + +function addMarker(map, latlng, title, subtext) { + const marker = L.marker(latlng, { icon: redDot }).addTo(map) + marker.bindPopup([ + "<b>", title, "</b>", + "<br>", + subtext, + ].join('')) +} + +function addArc(map, src, dest) { + L.bezier({ + path: [ + [ + { lat: src[0], lng: src[1] }, + { lat: dest[0], lng: dest[1] }, + ], + ] + }, arcStyle).addTo(map) +} + +export default function append(el, payload) { + const { data } = payload + let { paper, address } = data + let source = [0, 0] + const citations = getCitations(data) + + let map = L.map(el).setView([25, 0], 2) + L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', { + attribution: 'Map data © <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' + + '<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' + + 'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>', + maxZoom: 18, + id: 'mapbox.dark', + style: 'mapbox://styles/mapbox/dark-v9', + accessToken: 'pk.eyJ1IjoiZmFuc2FsY3kiLCJhIjoiY2pvN3I1czJwMHF5NDNrbWRoMWpteHlrdCJ9.kMpM5syQUhVjKkn1iVx9fg' + }).addTo(map) + + if (address) { + source = address.slice(3, 5).map(n => parseFloat(n)) + } + + citations.forEach(point => { + const latlng = [point.lat, point.lng] + if (Number.isNaN(latlng[0]) || Number.isNaN(latlng[1])) return + addMarker(map, latlng, point.title, point.location) + addArc(map, source, latlng) + }) + + addMarker(map, source, paper.title, paper.address) +} diff --git a/client/map/leaflet.bezier.js b/client/map/leaflet.bezier.js new file mode 100644 index 00000000..02adbe7f --- /dev/null +++ b/client/map/leaflet.bezier.js @@ -0,0 +1,261 @@ +import L from 'leaflet' + +L.SVG.include({ + _updatecurve: function (layer) { + let svg_path = this._curvePointsToPath(layer._points); + this._setPath(layer, svg_path); + + if (layer.options.animate) { + let path = layer._path; + let length = path.getTotalLength(); + + if (!layer.options.dashArray) { + path.style.strokeDasharray = length + ' ' + length; + } + + if (layer._initialUpdate) { + path.animate([ + {strokeDashoffset: length}, + {strokeDashoffset: 0} + ], layer.options.animate); + layer._initialUpdate = false; + } + } + + return svg_path; + }, + + + _curvePointsToPath: function (points) { + let point, curCommand, str = ''; + for (let i = 0; i < points.length; i++) { + point = points[i]; + if (typeof point === 'string' || point instanceof String) { + curCommand = point; + str += curCommand; + } else + str += point.x + ',' + point.y + ' '; + + + } + return str || 'M0 0'; + }, + +}); + +let Bezier = L.Path.extend({ + options: {}, + initialize: function (path, icon, options) { + + if (!path.mid || path.mid[0] === undefined) { + path.mid = this.getMidPoint(path.from, path.to, (path.from.deep ? path.from.deep : 4), path.from.slide); + } + + L.setOptions(this, options); + this._initialUpdate = true; + this.setPath(path); + this.icon = icon; + + }, + //Juast after path is added + onAdd: function (map) { + this._renderer._initPath(this); + this._reset(); + this._renderer._addPath(this); + + // TODO ajust plane acording to zoom + map.on('zoom', function(){ + + }); + + }, + // setAnimatePlane: function(path) { + + // if (this.spaceship_img) + // this.spaceship_img.remove(); + + // let SnapSvg = Snap('.leaflet-overlay-pane>svg'); + + // let spaceship_img = this.spaceship_img = SnapSvg.image(this.icon.path).attr({ + // visibility: "hidden" + // }); + + + // let spaceship = SnapSvg.group(spaceship_img); + // let flight_path = SnapSvg.path(path).attr({ + // 'fill': 'none', + // 'stroke': 'none' + // }); + + // let full_path_length = Snap.path.getTotalLength(flight_path); + // let half_path_length = full_path_length / 2; + // let third_path_length = full_path_length / 3; + // let forth_path_length = full_path_length / 4; + + + // let width = forth_path_length / this._map.getZoom(); + // let height = forth_path_length / this._map.getZoom(); + + // width = Math.min(Math.max(width, 30), 64); + // height = Math.min(Math.max(height, 30), 64); + + + // let last_step = 0; + + + // Snap.animate(0, forth_path_length, function (step) { + + // //show image when plane start to animate + // spaceship_img.attr({ + // visibility: "visible" + // }); + + // spaceship_img.attr({width: width, height: height}); + + // last_step = step; + + // let moveToPoint = Snap.path.getPointAtLength(flight_path, step); + + // let x = moveToPoint.x - (width / 2); + // let y = moveToPoint.y - (height / 2); + + + // spaceship.transform('translate(' + x + ',' + y + ') rotate(' + (moveToPoint.alpha - 90) + ', ' + width / 2 + ', ' + height / 2 + ')'); + + // }, 2500, mina.easeout, function () { + + // Snap.animate(forth_path_length, half_path_length, function (step) { + + // last_step = step; + // let moveToPoint = Snap.path.getPointAtLength(flight_path, step); + + // let x = moveToPoint.x - width / 2; + // let y = moveToPoint.y - height / 2; + // spaceship.transform('translate(' + x + ',' + y + ') rotate(' + (moveToPoint.alpha - 90) + ', ' + width / 2 + ', ' + height / 2 + ')'); + // }, 7000, mina.easein, function () { + // //done + + // }); + + // }); + + + // }, + getPath: function () { + return this._coords; + }, + setPath: function (path) { + this._setPath(path); + return this.redraw(); + }, + getBounds: function () { + return this._bounds; + }, + getMidPoint: function (from, to, deep, round_side = 'LEFT_ROUND') { + + let offset = 3.14; + + if (round_side === 'RIGHT_ROUND') + offset = offset * -1; + + let latlngs = []; + + let latlng1 = from, + latlng2 = to; + + let offsetX = latlng2.lng - latlng1.lng, + offsetY = latlng2.lat - latlng1.lat; + + let r = Math.sqrt(Math.pow(offsetX, 2) + Math.pow(offsetY, 2)), + theta = Math.atan2(offsetY, offsetX); + + let thetaOffset = (offset / (deep ? deep : 4)); + + let r2 = (r / 2) / (Math.cos(thetaOffset)), + theta2 = theta + thetaOffset; + + let midpointX = (r2 * Math.cos(theta2)) + latlng1.lng, + midpointY = (r2 * Math.sin(theta2)) + latlng1.lat; + + let midpointLatLng = [midpointY, midpointX]; + + latlngs.push(latlng1, midpointLatLng, latlng2); + + return midpointLatLng; + }, + _setPath: function (path) { + this._coords = path; + this._bounds = this._computeBounds(); + }, + _computeBounds: function () { + + let bound = new L.LatLngBounds(); + + bound.extend(this._coords.from); + bound.extend(this._coords.to);//for single destination + bound.extend(this._coords.mid); + + return bound; + }, + getCenter: function () { + return this._bounds.getCenter(); + }, + _update: function () { + if (!this._map) { + return; + } + this._updatePath(); + }, + _updatePath: function () { + //animated plane + let path = this._renderer._updatecurve(this); + // this.setAnimatePlane(path); + }, + _project: function () { + + this._points = []; + + this._points.push('M'); + + let curPoint = this._map.latLngToLayerPoint(this._coords.from); + this._points.push(curPoint); + + if (this._coords.mid) { + this._points.push('Q'); + curPoint = this._map.latLngToLayerPoint(this._coords.mid); + this._points.push(curPoint); + } + curPoint = this._map.latLngToLayerPoint(this._coords.to); + this._points.push(curPoint); + + + }, + + +}); + +L.bezier = function (config, options) { + let paths = []; + for (let i = 0; config.path.length > i; i++) { + let last_destination = false; + for (let c = 0; config.path[i].length > c; c++) { + + let current_destination = config.path[i][c]; + if (last_destination) { + let path_pair = {from: last_destination, to: current_destination}; + paths.push(new Bezier(path_pair, config.icon, options)); + } + + last_destination = config.path[i][c]; + } + } + return L.layerGroup(paths); + +}; + +function noop() {} + +export { + Bezier, + noop, +}
\ No newline at end of file |
