summaryrefslogtreecommitdiff
path: root/client/map
diff options
context:
space:
mode:
authorAdam Harvey <adam@ahprojects.com>2018-12-23 01:37:03 +0100
committerAdam Harvey <adam@ahprojects.com>2018-12-23 01:37:03 +0100
commit4452e02e8b04f3476273574a875bb60cfbb4568b (patch)
tree3ffa44f9621b736250a8b94da14a187dc785c2fe /client/map
parent2a65f7a157bd4bace970cef73529867b0e0a374d (diff)
parent5340bee951c18910fd764241945f1f136b5a22b4 (diff)
.
Diffstat (limited to 'client/map')
-rw-r--r--client/map/index.js78
-rw-r--r--client/map/leaflet.bezier.js261
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 &copy; <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