NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name FlagstackMap // @namespace flagstackmap.rocka.de // @include https://www.flagstack.net/map* // @version 1 // @grant unsafeWindow // @grant GM_getValue // @grant GM_setValue // @grant GM_addStyle // @grant GM_registerMenuCommand // @description Type filters, score sum and GPX exports for Flagstack Map // ==/UserScript== // // Features: // * filter visible Flags by type // * Total score display // * GPX Export: save visible Flags to a file for offline use // * change URL when clicking on Flag (reload to last shown Flag) (function () { var locale = 'de-DE', filters = JSON.parse(GM_getValue('filters')||'{}'), types = { own: { rgx: /_own_/, name: 'Own Flag', score: 0 }, captured: { rgx: /_captured_/, name: 'Captured Flag', score: 0 }, green: { rgx: /_green_/, name: 'Green Flag', score: 8 }, system: { rgx: /_orange_/, name: 'System Flag', score: 16 }, white: { rgx: /_white_/, name: 'White Flag', score: 10 }, personal: { rgx: /_personal_/, name: 'Personal Flag', score: 5 }, oracle: { rgx: /_oracle_/, name: 'Oracle Flag', score_min: 6, score_max: 40 }, premium: { rgx: /_premium_/, name: 'Premium Flag', score: 10 }, treasure: { rgx: /_treasure_/, name: 'Treasure Flag', score_min: 8, score_max: 60 }, company: { rgx: /_business_/, name: 'Company Flag', score: 1 }, party: { rgx: /_party_/, name: 'Party Flag', score: 0//? }, team: { rgx: /_team_/, name: 'Team Flag', score: 0 }, querfeldein_deutschland: { rgx: /\/(736699|7367(05|11|19|32|33)|10905(22|31|47|52|68|98)|10906(03|09|21|39))_/, name: 'Querfeldein durch Deutschland', score: 10, flags: { 736699: 'Schleswig-Holstein', 736705: 'Nordrhein-Westfalen', 736711: 'Saarland', 736719: 'Mecklenburg-Vorpommern', 736732: 'Sachsen', 736733: 'Thüringen', 1090522: 'Bremen', 1090531: 'Niedersachsen', 1090547: 'Hessen', 1090552: 'Rheinland-Pfalz', 1090568: 'Baden-Württemberg', 1090598: 'Hamburg', 1090603: 'Brandenburg', 1090609: 'Berlin', 1090621: 'Sachsen-Anhalt', 1090639: 'Bayern' } } }, groups = { physical: ['treasure'], virtual: ['green', 'system', 'white', 'personal', 'oracle', 'premium', 'company', 'party'], special: ['querfeldein_deutschland'] }, scoreElem, tmpl_gpx = '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?><gpx xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.1" xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1" xmlns="http://www.topografix.com/GPX/1/1" xmlns:rmc="urn:net:trekbuddy:1.0:nmea:rmc" creator="MunzeeMapNG" xmlns:wptx1="http://www.garmin.com/xmlschemas/WaypointExtension/v1" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd http://www.garmin.com/xmlschemas/WaypointExtension/v1 http://www.garmin.com/xmlschemas/WaypointExtensionv1.xsd" xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3" xmlns:ql="http://www.qlandkarte.org/xmlschemas/v1.1"><metadata><time><%time></time></metadata><%wpts><extensions/></gpx>', tmpl_wpt = '<wpt lon="<%lon>" lat="<%lat>"><time><%time></time><name><%name></name><cmt><%cmt></cmt><desc><![CDATA[<%desc>]]></desc><extensions><locus:icon>file:flagstack.zip:<%icon>.png</locus:icon></extensions></wpt>'; function isAnnotationVisible(annotation) { return unsafeWindow.map.getBounds().contains(annotation.getPosition()); } function refresh() { var score = 0, score_min = 0, score_max = 0, type_count = {}; $.each(unsafeWindow.annotations, function (flag_id, flag) { $.each(types, function (type, type_info) { if (type_info.rgx.test(flag.icon)) { if (filters[type] && flag.map !== null) { flag.setMap(null); } else if (!filters[type]) { if (flag.map === null) { flag.setMap(unsafeWindow.map); } if (isAnnotationVisible(flag)) { score_min += type_info.score_min ? type_info.score_min : type_info.score; score_max += type_info.score_max ? type_info.score_max : type_info.score; type_count[type] = (type_count[type] || 0) + 1; } } } }); }); score = (score_min + score_max) / 2; scoreElem.html(score.toLocaleString(locale) + ' Points'); if (score_min < score_max) { scoreElem.append('<br /><span>(' + score_min.toLocaleString(locale) + ' - ' + score_max.toLocaleString(locale) + ')</span>'); } var type_text = ''; for (var type in type_count) { if (type_count[type] > 0 && (types[type].score > 0 || types[type].score_min > 0)) { type_text += type_count[type] + ' ' + (types[type].name || (type.charAt(0).toUpperCase() + type.slice(1))) + ' Flags (' + (types[type].score_min > 0 ? (types[type].score_min * type_count[type]).toLocaleString(locale) + ' - ' + (types[type].score_max * type_count[type]).toLocaleString(locale) : (types[type].score * type_count[type]).toLocaleString(locale)) + ")\n"; } } scoreElem.attr('title', type_text); //console.log(type_text); } function createLink(id) { return annotations[id] ? '/map/?highlight=1&id=' + id + '&latitude=' + annotations[id].position.lat() + '&longitude=' + annotations[id].position.lng() : ''; } function useTmpl(tmpl, data) { var out = tmpl; $.each(data, function (key, value) { out = out.replace('<%' + key + '>', value); }); return out; } function createGPX() { var wpts = ""; $.each(unsafeWindow.annotations, function (flag_id, flag) { if (isAnnotationVisible(flag)) { $.each(types, function (type, type_info) { if (type_info.rgx.test(flag.icon) && !filters[type]) { wpts += useTmpl(tmpl_wpt, { lon: flag.getPosition().lng(), lat: flag.getPosition().lat(), time: "", name: flag.f_name + (type_info.name !== flag.f_name ? "(" + type_info.name + ")" : ""), cmt: flag.f_ownerUsername ? "by " + flag.f_ownerUsername : "", desc: flag.f_address, icon: type }); } }); } }); if (wpts) { window.open('data:text/plain,' + useTmpl(tmpl_gpx, { time: (new Date()).toISOString(), wpts: wpts })); } console.log('done', wpts); } GM_registerMenuCommand('Save Filters',function(){ GM_setValue('filters', JSON.stringify(filters)); },'s'); unsafeWindow.getMapItems = function () { var params = { section: 'mapItems', latitude: currentLocation.latitude, longitude: currentLocation.longitude, centerLocation: JSON.stringify(centerLocation), regionBounds: JSON.stringify(regionBounds), }; if (xhr) { xhr.abort(); } if (!requestID) { requestID = randomString(); } params.requestID = requestID; if (responseIDs.length > 0) { params.responseIDs = JSON.stringify(responseIDs); } xhr = $.getJSON('/api/?' + sid, params, function (jsonData) { if (jsonData.result === 'OK') { var newItems = 0; if (typeof (jsonData.responseID) !== 'undefined') { responseIDs.push(jsonData.responseID); } if (typeof (jsonData.items) !== 'undefined') { xhrItems = jsonData.items; for (var i = 0, len = jsonData.items.length; i < len; i++) { var itemID = jsonData.items[i].id; if (typeof (annotations[itemID]) === 'undefined') { annotations[itemID] = createAnnotation(jsonData.items[i]); if (highlight === 1 && itemID === highlightItemID && highlightInit) { highlightInit = false; new google.maps.event.trigger(annotations[itemID], 'click'); } newItems++; } } } } else if (jsonData.result == 'ERROR') { swal({ title: jsonData.title, text: jsonData.message, type: 'error', animation: false }); } refresh(); }); }; function createFilterBtn(type){ return '<dt>' + type.charAt(0).toUpperCase() + type.slice(1) + ' Flags</dt>' + '<dd><a href="#" class="filter" id="filter_'+type+'"><img src="/img/switch_'+(filters[type]?'off':'on')+'.png" width="63" height="32"></a></dd>'; } if ($('#map_filter')) { $('#map_filter').remove(); } $( '<div id="map_filter">'+ '<div class="grid">'+ '<p class="title">Filter</p>'+ '<div id="score_sum">0 Points</div>'+ '<div style="clear:both"></div>'+ '<div class="column">'+ '<dl>'+ createFilterBtn('own')+ createFilterBtn('captured')+ createFilterBtn('physical')+ createFilterBtn('virtual')+ createFilterBtn('special')+ '</dl>'+ '</div>'+ '<div class="column">'+ '<dl>'+ createFilterBtn('green')+ createFilterBtn('system')+ createFilterBtn('white')+ createFilterBtn('oracle')+ createFilterBtn('premium')+ '</dl>'+ '</div>'+ '<div class="column">'+ '<dl>'+ createFilterBtn('treasure')+ createFilterBtn('personal')+ createFilterBtn('company')+ createFilterBtn('team')+ createFilterBtn('party')+ '</dl>'+ '</div>'+ '</div>'+ '</div>' ).appendTo($('.container.white')); $(document).off('click', '.filter').on('click', '.filter', function () { var type = $(this).attr('id').replace(/^filter_/, ''), i; filters[type] = !filters[type]; if (groups[type]) { for (i = 0; i < groups[type].length; i++) { filters[groups[type][i]] = filters[type]; $('#filter_' + groups[type][i]).children('img').attr('src', filters[type] ? '/img/switch_off.png' : '/img/switch_on.png'); } }else{ var el; $.each(groups,function(group,flags){ if (filters[group] && !filters[type] && flags.indexOf(type) !== -1 && (el = $('#filter_'+group))) { filters[group] = false; el.children('img').attr('src', '/img/switch_on.png'); } }); } $(this).children('img').attr('src', filters[type] ? '/img/switch_off.png' : '/img/switch_on.png'); refresh(); return false; }); $('#map-container').on('click', function () { if ($('.gm-style-iw .annotationInfoWindow').size()>0) { history.pushState(null, '', createLink($('.gm-style-iw .annotationInfoWindow')[0].getAttribute('data-id'))); } }); GM_addStyle( ".gm_btn {margin: 10px;z-index: 0;position: absolute;cursor: pointer;right: 0px;top: 60px;}" + ".gm_btn > div {font-weight:bold;direction: ltr; overflow: hidden; text-align: center; position: relative; color: rgb(0, 0, 0); font-family: Roboto, Arial, sans-serif; -webkit-user-select: none; font-size: 11px; padding: 8px; -webkit-background-clip: padding-box; box-shadow: rgba(0, 0, 0, 0.298039) 0px 1px 4px -1px; border-left-width: 0px; min-width: 39px; font-weight: 500; background-color: rgb(255, 255, 255); background-clip: padding-box;}" + ".gm_btn > div:hover {color:black;background-color: rgb(235, 235, 235);}" + "#score_sum {float:right;margin:0 55px 12px 0;font-size:x-large;line-height:22px}" + "#score_sum span {font-size:smaller}" ); scoreElem = $('#score_sum'); $('footer').remove(); //unsafeWindow.setMapFilter = setFilter; jQuery(document).ready(function ($) { setTimeout(function () { $('<div id="createGPX" class="gm-style-mtc gm_btn"><div>GPX</div></div>') .on('click', createGPX).appendTo($('.gm-style')); }, 500); }); })();