var RoutingController = Backbone.Model.extend({ options: {}, allCrossovers: null, currentCrossover: null, currentRoutingpoint: null, crossovers: { all: { 200: [200, 201, 203, 204, 207, 208, 209, 210, 211, 212, 213, 215, 216, 217, 218, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233], 300: [300, 305, 309, 311, 313, 314, 316, 318, 319, 321, 322, 323, 324, 329, 330, 331, 333], 400: [400, 406, 410, 412, 413, 414, 415, 417, 420, 421, 422, 423, 425, 428, 430, 431, 432], 500: [500, 501, 502, 503, 516, 517, 518, 519, 520, 524, 525, 526, 527, 528, 531, 533], 600: [600, 601, 602, 604, 615, 617, 618, 619, 620, 624, 625, 626, 627, 629, 630, 632], 700: [700, 706, 707, 712, 721, 723, 726, 732], 800: [833, 800, 805, 808, 811, 822, 823, 827], }, angles: { 0: {angle: -45, tolerance: 30}, 1: {angle: 0, tolerance: 15}, 2: {angle: 45, tolerance: 30}, 3: {angle: 90, tolerance: 15}, 4: {angle: 135, tolerance: 30}, 5: {angle: 180, tolerance: 15}, 6: {angle: -135, tolerance: 30}, 7: {angle: -90, tolerance: 15}, } }, // Initialisierung initialize: function(options) { var that = this; $.extend(true, that.options, options); this.setRoadbookHandler(); $('#editor-routing-edit .left .routing-image').not('.gr').click(that.changeCrossoverType); }, addCrossover: function() { var that = application.controller.routing; application.controller.map.drawRouting(); }, editRoutingpoint: function(co) { var that = application.controller.routing; that.currentRoutingpoint = null; that.currentCrossover = co; application.controller.map.openMapModal('editor-routing-edit'); $('#editor-routing-edit .crossover-routings').html(''); $('#editor-routing-edit .map-modal-header span').text(co.id); var found = null; if (co.type < 256) { $.each(co.routingpoints, function(i, rp) { rp.experience = co.experience; var routing = $('
').appendTo('#editor-routing-edit .crossover-routings'); var rpCode = that.getCodeOfRoutingpoint(rp, co); var src = $('#editor-routing-edit .left .routing-image').attr('data').replace(':crossover', rpCode).replace(':angleType', rp.type); if (co.type >= 256) { src = src.substr(0, src.lastIndexOf('/') + 1) + co.type + '.png\')'; } $('div', routing).css('background-image', src); if (co.type < 256 && rp.type < 8) { $('div', routing).rotate(parseFloat(rp.angleIn)); } $(routing).click(function() { that.selectActiveRouting(rp); }); if (found == null && rp.found) { found = rp; } }); } var isMissing = false; if (co.type < 256) { $.each(co.tps, function(i, cotp) { if (cotp.found !== true) { isMissing = true; } }); } if (isMissing && co.type < 256) { $('#editor-routing-edit .crossover-routing-add').show(); } else { $('#editor-routing-edit .crossover-routing-add').hide(); } $('#editor-routing-edit .left .routing-image div').css('background-image', ''); $('#routing-description').val(''); if (found !== null && co.type < 256) { that.selectActiveRouting(found); } else { that.selectActiveRouting(co.routingpoints[0]); } }, changeCrossoverType: function() { var co = application.controller.routing.currentCrossover; var rp = co.routingpoints[0]; var angles = application.controller.map.getAnglesOfTrackpoint(co.experience.track, rp.tp.index); application.controller.routing.selectNewCrossOfAngles(angles, function(crossoverType, angleType) { rp.type = angleType; var co = application.controller.routing.currentCrossover; co.type = crossoverType; console.log(angles, rp, co) application.controller.experience.saveRoutingpoint(rp, co, function(data) { co = data.crossover; rp = data.routing; // co.routingpoints = [rp]; application.controller.map.refreshRoutingpoints(application.controller.map.edit.element[0].experience); application.controller.routing.reloadRoadbook(application.controller.map.edit.element[0].experience); application.controller.event.trigger('map.routing.draw.success'); }); }); }, getNewDetailObject: function() { var detail = { to: {type: 'text', value: ''}, streetnumber: {type: 'text', value: ''}, streetname: {type: 'text', value: ''}, mark: {type: 'text', value: ''}, feature: {type: 'text', value: ''}, other: {type: 'text', value: ''}, heading: {type: 'checkbox', value: false}, underground: {type: 'checkbox', value: false}, climb: {type: 'checkbox', value: false}, next: {type: 'checkbox', value: false}, } return $.extend({}, detail); }, setRoutingDetails: function(rp) { var that = this; if (rp.description == '') { rp.description = that.getNewDetailObject(); } else if (typeof(rp.description) !== 'object') { rp.description = JSON.parse(rp.description); } $.each (rp.description, function(key, detail) { if (detail.type == 'text') { $('#routing-detail-' + key).val(detail.value); } else if (detail.type == 'checkbox') { $('#routing-detail-' + key).prop('checked', detail.value); } }); }, selectActiveRouting: function(rp) { var that = application.controller.routing; var co = that.currentCrossover; if (that.currentRoutingpoint !== null) { that.saveRoutingpoint(); } that.currentRoutingpoint = rp; if (rp.tp == undefined) rp.tp = co.tps[0]; var rpCode = that.getCodeOfRoutingpoint(rp, that.currentCrossover); var src = $('#editor-routing-edit .left .routing-image').attr('data').replace(':crossover', rpCode).replace(':angleType', rp.type); if (co.type >= 256) { src = src.substr(0, src.lastIndexOf('/') + 1) + co.type + '.png\')'; } $('#editor-routing-edit .left .routing-image div').css('background-image', src); if (rp.type < 8) { $('#editor-routing-edit .left .routing-image div').rotate(parseFloat(rp.angleIn)); } application.controller.map.map.setView([rp.lat, rp.lon], 19); that.setRoutingDetails(rp); if (co.type < 256 && !that.createOpposite(false)) { $('#editor-routing-edit .left .routing-image.gr').show(); } else { $('#editor-routing-edit .left .routing-image.gr').hide(); } }, saveRoutingpoint: function(close) { var that = application.controller.routing; var co = that.currentCrossover; var rp = that.currentRoutingpoint; $.each (rp.description, function(key, detail) { if (detail.type == 'text') { rp.description[key].value = $('#routing-detail-' + key).val(); } else if (detail.type == 'checkbox') { rp.description[key].value = $('#routing-detail-' + key).is(':checked'); } }); application.controller.experience.saveRoutingpoint(rp, co, function() {that.reloadRoadbook(rp.experience);}); if (close === true) { application.controller.map.closeMapModal('editor-routing-edit'); } }, removeRoutingpoint: function() { var that = application.controller.routing; var co = that.currentCrossover; application.controller.map.closeMapModal('editor-routing-edit'); if (co !== null) { application.controller.experience.removeCrossover(co, function() { $.each(co.experience.routingpoints, function(i, eco) { if (co == eco) { var experience = co.experience; experience.routingpoints.splice(i, 1); delete (co); that.currentCrossover = null; that.currentRoutingpoint = null; application.controller.map.refreshRoutingpoints(experience); } }); }); } }, getCountOfCrossoverSymbols: function(type) { var that = this; var crossType = parseInt(type) % 100; var count = 0; $.each(that.crossovers.all, function(i, a) { var t = parseInt(i) + crossType; if (a.indexOf(t) !== -1) { count++; } }); var existSymbols = count * that.crossovers.relations[crossType].length; var situations = count*(count+1); return {existSymbols: existSymbols, situations: situations}; }, createOpposite: function(execute) { var that = this; var co = that.currentCrossover; var rp = that.currentRoutingpoint; var type = rp.type; switch (parseInt(rp.type)) { case 0: type = 2; break; case 2: type = 0; break; case 3: type = 7; break; case 4: type = 6; break; case 6: type = 4; break; case 7: type = 3; break; } var angles = application.controller.map.getAnglesOfTrackpoint(rp.experience.track, rp.tp.index); var angleIn = parseFloat(angles.angleOut) - 180; while (angleIn > 180) { angleIn -= 360; } while (angleIn < -180) { angleIn += 360; } var found = false; var angleType = that.getTypeOfAngle(angleIn); $.each(that.currentCrossover.routingpoints, function(i, corp) { var rpAngleType = that.getTypeOfAngle(corp.angleIn); if (angleType == rpAngleType && corp.type == type) { found = true; if (execute !== false) { that.selectActiveRouting(corp); } } }); if (!found && execute !== false) { that.selectAddRoutingToCrossover(type, angleIn); } return found; }, addRoutingToCrossover: function() { var that = application.controller.routing; var co = that.currentCrossover; var found = false; var angles; var foundTypes = []; $.each(co.tps, function(i, cotp) { if (cotp.found || found) { return true; } angles = application.controller.map.getAnglesOfTrackpoint(co.experience.track, cotp.index); cotp.found = true; found = true; }); var tangle = angles.angleOut - angles.angleIn; if (tangle > 180) { tangle -= 360; } if (tangle < -180) { tangle += 360; } var angleType = that.getTypeOfAngle(tangle); var diff = co.angle - angles.angleIn; if (diff > 180) { diff -= 360; } if (diff < -180) { diff += 360; } var diffType = (application.controller.routing.getTypeOfAngle(diff) - 1) % 8; var code = application.controller.routing.getAllCrossovers()[co.type]; var newCode = application.controller.routing.shiftCode(code, diffType); var type = that.getIdOfCode(newCode); application.controller.routing.selectAddRoutingToCrossover(angleType, angles.angleIn); }, shiftCode: function(code, diff) { diff = (diff + 8) % 8; if (diff > 0) { code = code.substr(-diff) + code.substr(0, code.length - diff); } return code; }, getIdOfCode: function(code) { var that = this; var found = null; $.each(that.getAllCrossovers(), function(i, crossover) { if (code == crossover) { found = i; } }); return found; }, getCodeOfRoutingpoint: function(rp, co) { var diff = co.angle - rp.angleIn; if (diff > 180) { diff -= 360; } if (diff < -165) { diff += 360; } var diffType = application.controller.routing.getTypeOfAngle(diff) ; diffType = (diffType - 1) % 8; var code = application.controller.routing.getAllCrossovers()[co.type]; var rpCode = application.controller.routing.shiftCode(code, diffType); return rpCode; }, getAllCrossovers: function() { var that = this; if (that.allCrossovers == null) { that.allCrossovers = {}; var numberOfStreets = 8; var numberOfCodes = Math.pow(2, numberOfStreets); for (var i = 0; i < numberOfCodes; i++) { var number = that.decbin(i); var code = that.str_pad(number, numberOfStreets, '0', 'STR_PAD_LEFT'); var count = that.substr_count(code, '1'); if (count >= 1 && code[5] == '1' && i !== 4) { that.allCrossovers[i] = code; } } } return that.allCrossovers; }, openRoutingChoose: function(crossovers, angleType, angleIn, callback) { var that = this; $('#editor-routing-choose .routing-choose').not('.dummy').remove(); var click = function() { var id = $(this).attr('data'); application.controller.map.closeMapModal('editor-routing-choose'); callback(id); }; $.each(crossovers, function(i, id) { var icon = $('#editor-routing-choose .dummy').clone(); $(icon).attr('data', i).removeClass('hidden').removeClass('dummy'); var src = $('.routing-image', icon).attr('data').replace(':crossover', id).replace(':angleType', angleType); $('.routing-image', icon).css('background-image', src).rotate(parseFloat(angleIn)); var count = that.substr_count(id, '1')-2; $(icon).insertAfter('#editor-routing-choose .map-modal-body a[name=routing-image-anchor-' + count +']'); $(icon).on('click', click); }); application.controller.map.closeMapModal('editor-routing-edit'); application.controller.map.openMapModal('editor-routing-choose'); }, selectNewCrossOfAngles: function(angles, callback) { var that = this; var tangle = angles.angleOut - angles.angleIn; if (tangle > 180) { tangle -= 360; } if (tangle < -180) { tangle += 360; } var angleType = that.getTypeOfAngle(tangle); var crossovers = {}; $.each(that.getAllCrossovers(), function(i, crossover) { if (crossover[angleType] == '1') { crossovers[i] = crossover; } }); that.openRoutingChoose(crossovers, angleType, angles.angleIn, function(crossoverType) { callback(crossoverType, angleType); }); }, selectAddRoutingToCrossover: function(type, angleIn) { var that = application.controller.routing; var co = that.currentCrossover; var rp = {lat: co.lat, lon: co.lon, type: type, angleIn: angleIn, description: that.getNewDetailObject()}; $.each(co.routingpoints, function(i, corp) { if (typeof(corp.description) == 'object' && corp.description.feature.value !== '') { rp.description.feature.value = corp.description.feature.value; } }); co.routingpoints.push(rp); application.controller.map.refreshRoutingpoints(co.experience); //that.selectActiveRouting(rp); that.saveRoutingpoint(); that.editRoutingpoint(co); that.selectActiveRouting(rp); }, reloadRoadbook: function(experience) { application.controller.experience.getRoadbook(experience, function(html) { $('.tour-edit.roadbook').html(html); $('.net-tour-edit.roadbook').html(html); application.controller.routing.setRoadbookHandler(); }); }, setRoadbookHandler: function () { $('.roadbook .routing-image').click(function() { var cid = $(this).data('id'); $('.abs-routing-icon[c=' + cid + ']').trigger('click') }); }, getTypeOfAngle: function(angle) { var that = this; var found = null; if (parseFloat(angle) < -165) { angle = parseFloat(angle) + 360; } $.each(that.crossovers.angles, function(i, a) { if (Math.abs(angle - a.angle) < a.tolerance) { found = i; } }); return parseInt(found); }, toggleRoutingSelection: function() { $('#roadbook .roadbook-entry').each(function() { var val = $(this).prop('checked'); $(this).prop('checked', !val); }); }, saveRoutingSelection: function() { var ids = []; $('#roadbook .roadbook-entry').each(function() { if ($(this).is(':checked')) { var id = parseInt($(this).attr('data')); ids.push(id); } }); application.controller.experience.saveRoutingSelection(application.router.editor.experience, ids); }, decbin: function(number) { if (number < 0) { number = 0xFFFFFFFF + number + 1; } return parseInt(number, 10).toString(2); }, str_pad: function(input, pad_length, pad_string, pad_type) { var half = '', pad_to_go; var str_pad_repeater = function (s, len) { var collect = '', i; while (collect.length < len) { collect += s; } collect = collect.substr(0, len); return collect; }; input += ''; pad_string = pad_string !== undefined ? pad_string : ' '; if (pad_type !== 'STR_PAD_LEFT' && pad_type !== 'STR_PAD_RIGHT' && pad_type !== 'STR_PAD_BOTH') { pad_type = 'STR_PAD_RIGHT'; } if ((pad_to_go = pad_length - input.length) > 0) { if (pad_type === 'STR_PAD_LEFT') { input = str_pad_repeater(pad_string, pad_to_go) + input; } else if (pad_type === 'STR_PAD_RIGHT') { input = input + str_pad_repeater(pad_string, pad_to_go); } else if (pad_type === 'STR_PAD_BOTH') { half = str_pad_repeater(pad_string, Math.ceil(pad_to_go / 2)); input = half + input + half; input = input.substr(0, pad_length); } } return input; }, substr_count: function(haystack, needle, offset, length) { var cnt = 0; haystack += ''; needle += ''; if (isNaN(offset)) { offset = 0; } if (isNaN(length)) { length = 0; } if (needle.length == 0) { return false; } offset--; while ((offset = haystack.indexOf(needle, offset + 1)) != -1) { if (length > 0 && (offset + needle.length) > length) { return false; } cnt++; } return cnt; }, });