(function () { 'use strict'; function InsertMapDirective($compile, $templateCache) { function link($scope, elem) { var segments = $scope.segments, pictureBaseUrl = (segments || {}).pictureBaseUrl || 'pictures/', picturesData = (segments || {}).picturesData; var list = segments.list(); var topLeft = $scope.topLeft, topRight = $scope.topRight, bottomLeft = $scope.bottomLeft, bottomRight = $scope.bottomRight; var div = elem[0]; var map = L.map(div); if (!pictureBaseUrl.match(/\/$/)) { pictureBaseUrl = pictureBaseUrl + '/'; } var outerBounds; var count = list.length; function createIcon(location, className, html) { var icon = L.divIcon({ className: className, html: html }); return L.marker(location, {icon: icon}); } angular.forEach(list, function (segment, index) { var className = 'segment-' + index; var gpxLayer; segment.gpx.then(function (gpx) { gpxLayer = new L.GPX(gpx, { marker_options: { // define where the icons are startIconUrl: undefined && 'bower_components/leaflet-gpx/pin-icon-start.png', endIconUrl: undefined && 'bower_components/leaflet-gpx/pin-icon-end.png', shadowUrl: undefined && 'bower_components/leaflet-gpx/pin-shadow.png' }, polyline_options: { className: className, color: segment.color }, clickable: false }) .on('loaded', function (e) { var layer = e.target; var bounds = e.target.getBounds(); segment.bounds = bounds; segment.start = e.target.get_start(); segment.end = e.target.get_end(); if (outerBounds) { outerBounds.extend(bounds); } else { outerBounds = bounds; } // console.log('Box for ' + segment.title, bounds); count--; if (count == 0) { console.log('Loaded all maps, outerBounds', outerBounds); map.fitBounds(outerBounds); angular.forEach(list, function (s, index) { var icon; if (index == 0) { createIcon(s.start, 'icon-start', "") .addTo(map); } if (index == list.length - 1) { createIcon(s.end, 'icon-end', "") .addTo(map); } else { //createIcon(s.end, 'icon-stop', "") // .addTo(map); } }); L.marker(segments.last.end, { icon: L.divIcon({ className: 'icon-end', html: "" }) }).addTo(map); } layer.addTo(map); }); }); segment.on('blur', function () { // TODO: make normal //gpxLayer.setStyle({color: 'blue'}); }); segment.on('focus', function () { // TODO: make wider //gpxLayer.setStyle({color: 'red'}); }); }); var osmLayer = L.tileLayer('//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap contributors' + '| Font Awesome' }); osmLayer.addTo(map); if (picturesData) { var options = { styleXX: function (feature) { console.log('feature', feature); }, onEachFeature: function (feature, layer) { var width = 200, height = 150; var popupOptions = { maxWidth: width, minWidth: width, closeButton: false }; var canvas = document.createElement('canvas'); //canvas.setAttribute("height", '' + height); //canvas.setAttribute("width", '' + width); //canvas.setAttribute("height", '' + (height * 2)); //canvas.setAttribute("width", '' + (width * 2)); var ctx = canvas.getContext("2d"); var img = new Image(); img.addEventListener('load', function () { var rotate = Math.abs(feature.properties.orientation) == 90; var scale, aspect; scale = width / img.width; var w, h; if (rotate) { //scale = height / img.height; aspect = img.width / img.height; w = width; h = img.height * scale; console.log('img', img.width + 'x' + img.height, 'scale', scale, aspect, feature.properties.orientation, 'size', w + 'x' + h); /* //ctx.scale(scale, scale); ctx.translate(width / 2, height / 2); ctx.rotate(feature.properties.orientation * Math.PI / 180); */ ctx.beginPath(); ctx.moveTo(0, 0); ctx.lineTo(width, 0); ctx.lineTo(width, height); ctx.lineTo(0, height); ctx.lineTo(0, 0); //ctx.lineWidth = 5; //ctx.strokeStyle = 'blue'; ctx.stroke(); ctx.translate(width / 2, height / 2); ctx.rotate(feature.properties.orientation * Math.PI / 180); //ctx.rotate(10 * Math.PI / 180); ////ctx.scale(scale, scale); // ctx.drawImage(img, -width/2, -height/2, width, height); } else { //ctx.scale(scale, scale); //ctx.drawImage(img, 0, 0); ctx.drawImage(img, 0, 0, width, img.height * scale); } }); img.src = pictureBaseUrl + feature.id; var span = document.createElement('a'); span.setAttribute('href', pictureBaseUrl + feature.id); span.textContent = feature.id; var div = document.createElement('div'); div.appendChild(canvas); div.appendChild(span); layer.bindPopup(div, popupOptions); }, filter: function (feature, layer) { return true; } }; var picturesLayer = L.geoJson(undefined, options).addTo(map); picturesData.then(function (json) { console.log('geo json', json); picturesLayer.addData(json); }); } function createLegend(position, templateUrl) { console.log('Creating legend for ' + position + ' from ' + templateUrl); var legend = L.control({position: position}); legend.onAdd = function () { var div = L.DomUtil.create('div', 'info legend'); var t = $templateCache.get(templateUrl); if (!t) { throw "Could not load template: " + bottomRight; } var compiled = $compile(t); var fragment = compiled($scope); if (fragment.length != 1) { throw "Invalid template, must contain exactly one root element."; } return fragment[0]; }; return legend; } topLeft && createLegend('topleft', topLeft).addTo(map); topRight && createLegend('topright', topRight).addTo(map); bottomLeft && createLegend('bottomleft', bottomLeft).addTo(map); bottomRight && createLegend('bottomright', bottomRight).addTo(map); } return { restrict: 'E', template: '
', scope: { segments: '=', topLeft: '=', topRight: '=', bottomLeft: '=', bottomRight: '=' }, replace: true, link: link } } function GpxGalleryController($http, $q, $injector) { function Segments() { var self = this; var list = []; var failed = false; self.picturesUrl = undefined; //self.colors = ['#a6cee3', '#1f78b4', '#b2df8a', '#33a02c', '#fb9a99', '#e31a1c', '#fdbf6f', '#ff7f00', '#cab2d6', '#6a3d9a', '#ffff99', '#b15928']; //self.colors = ['#feebe2', '#fbb4b9', '#f768a1', '#c51b8a', '#7a0177']; //self.colors = [ '#fc9272', '#fb6a4a', '#ef3b2c', '#cb181d', '#a50f15', '#67000d']; self.colors = ['#00441b', '#4d004b', '#084081', '#7f0000']; var scope = $injector.get('$rootScope'); this.on = function (name, listener) { scope.$on(name, listener); }; this.add = function (gpxUrl, title) { list.push(new Segment(this, list.length, scope.$new(), gpxUrl, title)); return this; }; this.init = function () { var count = list.length; angular.forEach(list, function (segment, index) { segment.first = index == 0; segment.last = index == count - 1; segment.middle = !segment.first && !segment.last; }); self.first = list[0]; self.last = list[list.length - 1]; angular.forEach(list, function (segment) { $http.get(segment.gpxUrl).then(function (res) { segment.process(res.data); }, function () { failed = true; }).finally(function () { count--; if (count == 0) { console.log('All GPX files loaded'); ctrl.ready = true; } }); }); if (self.picturesUrl) { self.picturesData = $http.get(self.picturesUrl).then(function (res) { return res.data; }); } }; this.list = function () { return list; }; this.focus = function (segment) { angular.forEach(list, function (s) { if (s === segment) { s.emit('focus', {segment: s}); } else { s.emit('blur', {segment: s}); } }); }; } function Segment(segments, index, scope, gpxUrl, name) { var segment = this; this.gpxUrl = gpxUrl; this.title = name; this.color = segments.colors[index % segments.colors.length]; this.broadcast = scope.$broadcast; this.on = function (name, listener) { scope.$on(name, listener); }; this.emit = function (name, args) { scope.$emit(name, args); }; var gpxQ = $q.defer(); this.gpx = gpxQ.promise; this.process = function (string) { console.log("GPX for " + this.title + " loaded"); gpxQ.resolve(string); }; this.focus = function () { segments.focus(this); }; } var ctrl = this; ctrl.ready = false; ctrl.segments = new Segments() .add('gpx/I villreinens forspor, dag 1.gpx', 'Dag 1') .add('gpx/I villreinens forspor, dag 2.gpx', 'Dag 2') .add('gpx/I villreinens forspor, dag 3.gpx', 'Dag 3') .add('gpx/I villreinens forspor, dag 4.gpx', 'Dag 4'); ctrl.segments.pictureBaseUrl = 'https://trygvis.io/~trygvis/2015/08/i-villreinens-fotspor/pictures'; ctrl.segments.picturesUrl = 'https://trygvis.io/~trygvis/2015/08/i-villreinens-fotspor/pictures/index.php'; ctrl.segments.init(); } angular .module('gpx-gallery', []) .directive('insertMap', InsertMapDirective) .controller('GpxGalleryController', GpxGalleryController); }());