Ë
    ‹$jt3  ã                   óP   — d dl Z d dlZd dlZ ed«       dZd„ Zedk(  r e«        yy)é    NzContent-type: text/html
uT2  <!doctype html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><meta name="description" content="amateur radio, radio experimenters, transmitter, hobby, electronics, communications, construction, ham radio, amateur radio activities in Ireland"><meta name="keywords" content="amateur radio, Ireland, hobby, radio, radio experimenters, electronics, communications, construction, ham radio"><title>IRTS â€“ Amateur Radio Voice Repeaters Map</title><link href="https://fonts.googleapis.com/css?family=Open+Sans%7CNunito%7CRoboto+Slab" rel="stylesheet" type="text/css"><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.min.css"><link rel="icon" href="https://www.irts.ie/imgs/key/favicon.ico"><link rel="stylesheet" href="https://www.irts.ie/styles/irts16c_2.css"><script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.min.js"></script><style>
#map {
    height: 600px;
    width: 100%;
    margin-bottom: 20px;
    border: 2px solid #999;
    border-radius: 4px;
    background-color: #e1e1e1;
}
.legend {
    background: white;
    padding: 10px;
    border-radius: 5px;
    box-shadow: 0 0 15px rgba(0,0,0,0.2);
    line-height: 18px;
    color: #555;
    font-size: 12px;
}
.legend i {
    width: 18px;
    height: 18px;
    float: left;
    margin-right: 8px;
    border-radius: 50%;
    border: 1px solid #999;
}
.map-controls {
    background: white;
    padding: 10px;
    border-radius: 5px;
    margin-bottom: 10px;
}
.map-controls button {
    padding: 8px 15px;
    margin-right: 5px;
    background-color: #007bff;
    color: white;
    border: none;
    border-radius: 3px;
    cursor: pointer;
    font-size: 12px;
}
.map-controls button:hover {
    background-color: #0056b3;
}
.repeater-count {
    padding: 10px;
    background-color: #f0f0f0;
    border-radius: 3px;
    margin-bottom: 10px;
    font-weight: bold;
}
</style></head><body><div class="banner"><a href="index.cgi"><img class="b_displayed mbm25" src="https://www.irts.ie/imgs/key/irts-banner16b.png" alt="IRTS Logo"></a><input type="checkbox" id="css3menu-switcher" class="c3m-switch-input">
<ul id="css3menu1" class="topmenu">	<li class="switch"><label onclick="" for="css3menu-switcher"></label></li>	<li class="topmenu"><a href="index.cgi">Home</a></li>	<li class="topmenu"><a href="#">Licensing &raquo;</a>	<ul>		<li><a href="st.cgi?licensing">Amateur Radio Licensing</a></li>		<li><a href="st.cgi?syllabus">Exam Syllabus</a></li>		<li><a href="st.cgi?applying">Applying for an Exam</a></li>		<li><a href="st.cgi?training">HAREC Exam Training</a></li>		<li><a href="st.cgi?study">Study Guide</a></li>		<li><a href="st.cgi?morse_test">Morse Test</a></li>    		<li><a href="st.cgi?theory">Radio Theory Links</a></li>	</ul></li>	<li class="topmenu"><a href="#">Membership &raquo;</a>	<ul>		<li><a href="st.cgi?joinus">Join IRTS</a></li>		<li><a href="st.cgi?renewpp">Renew Membership</a></li>	</ul></li>	<li class="topmenu"><a href="#">Information &raquo;</a>	<ul>		<li><a href="thisweek.cgi">This Week's News</a></li>		<li><a href="affiliat.cgi">Radio Clubs</a></li>		<li><a href="#"><span>Who&rsquo;s Who?</span></a>		<ul>			<li><a href="st.cgi?contactus">Useful Contacts</a></li>			<li><a href="officers.cgi">Officers</a></li>			<li><a href="committee.cgi">Committee</a></li>			<li><a href="st.cgi?sub_committees">Sub-committees and<br/>Working Groups</a></li>			<li><a href="st.cgi?honorary">Honorary Members</a></li>			<li><a href="st.cgi?pastpres">Past Presidents</a></li>		</ul></li>		<li><a href="st.cgi?downloads">Downloads</a></li>		<li><a href="repeater.cgi">Voice Repeaters</a></li>		<li><a href="repeater_map.cgi" style="font-weight: bold;">Voice Repeaters Map</a></li>		<li><a href="gateway.cgi">Internet Gateways</a></li>		<li><a href="beacons.cgi">Beacons In Ireland</a></li>		<li><a href="st.cgi?visitors">Visitors</a></li>		<li><a href="dxcc_list.cgi">EI DXCC List</a></li>		<li><a href="show_iota_list.cgi">EI IOTA Standings Table</a></li>		<li><a href="newsarchive.cgi">News Bulletin Archive</a></li>		<li><a href="st.cgi?elib">EiNews Archive</a></li>    	<li><a href="st.cgi?lib">Publications Library</a></li>        <li><a href="st.cgi?ei2b">Experiments by EI2B/B</a></li>	</ul></div><div class="pagecontent">
<h1>Voice Repeaters in Ireland<br>(Interactive Map View)</h1>    <a href="repeater.cgi"><img class="pfr" src="https://www.irts.ie/imgs/key/pfriendly_btn.png" alt="table view"></a>  

<div class="map-controls">
    <button onclick="showAllRepeaters()">Show All</button>
    <button onclick="filterByBand('HF')">HF Band</button>
    <button onclick="filterByBand('VHF')">VHF Band</button>
    <button onclick="filterByBand('UHF')">UHF Band</button>
    <button onclick="filterByBand('SHF')">SHF Band</button>
    <button onclick="filterByStatus('online')">Online Only</button>
    <button onclick="filterByStatus('all')">All Status</button>
</div>

<div class="repeater-count">
    Total Repeaters: <span id="repeater-count">0</span> | Visible: <span id="visible-count">0</span>
</div>

<div id="map"></div>

<div class="infobox1">
    <p class="pb4">Click on any marker to see repeater details.</p>
    <p class="pb4">&#8225; These repeaters make up the Southern Ireland Repeater Network. Keepers are EI8JA/EI3JE. IRLP node 5883 is accessible on all repeaters on the network.</p>
    <p class="pb4">1750Hz = audible tone-burst, 88.5Hz etc. = CTCSS</p>
    <p>Note that some 70cm repeaters have a 1.6MHz split, while others have a 7.6MHz split (+/-)</p>
</div>

<div class="decoration"></div>
</div><div class="button-group"><div class="one-half-pc"><a href="gateway.cgi" class="button button-yellow">Internet Gateways<br><span class="smalr">read more</span></a></div><div class="one-half-pc last-column"><a href="st.cgi?vhf" class="button button-purple">VHF / UHF / SHF<br><span class="smalr">read more</span></a></div></div><div class="pagecontent"><div class="decoration"></div><div class="container no-bottom"><div class="one-half-pc full-bottom">  <a href="st.cgi?contactus"><img class="displayed" src="https://www.irts.ie/imgs/key/contact130_btn.png" alt="contact IRTS"></a></div><div class="one-half-pc last-column full-bottom">  <a href="http://irts.groups.io/"><img class="displayed" src="https://www.irts.ie/imgs/key/groupsdotio_btn.png" alt="irts groups.io"></a></div>
</div><div class="decoration"></div></div></div>

<script>
var map;
var allMarkers = [];
var currentFilter = { band: null, status: 'all' };

var markerIconHtml = {
    'red': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M12 0C5.925 0 1 4.925 1 11c0 5.25 5.898 11.8 11 12.9c5.102-1.1 11-7.65 11-12.9 0-6.075-4.925-11-11-11zm0 15c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4z" fill="%23ff3333"/></svg>',
    'blue': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M12 0C5.925 0 1 4.925 1 11c0 5.25 5.898 11.8 11 12.9c5.102-1.1 11-7.65 11-12.9 0-6.075-4.925-11-11-11zm0 15c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4z" fill="%233366ff"/></svg>',
    'green': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M12 0C5.925 0 1 4.925 1 11c0 5.25 5.898 11.8 11 12.9c5.102-1.1 11-7.65 11-12.9 0-6.075-4.925-11-11-11zm0 15c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4z" fill="%2300cc44"/></svg>',
    'yellow': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M12 0C5.925 0 1 4.925 1 11c0 5.25 5.898 11.8 11 12.9c5.102-1.1 11-7.65 11-12.9 0-6.075-4.925-11-11-11zm0 15c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4z" fill="%23ffcc00"/></svg>'
};

function getMarkerIcon(color) {
    return L.icon({
        iconUrl: 'data:image/svg+xml;base64,' + btoa(markerIconHtml[color] || markerIconHtml.blue),
        iconSize: [32, 40],
        iconAnchor: [16, 40],
        popupAnchor: [0, -40]
    });
}

function initializeMap() {
    map = L.map('map').setView([53.5, -7.5], 7);
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        maxZoom: 19,
        attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(map);
    
    fetch('scripts/repeaters_automated.geojson')
        .then(function(response) {
            if (!response.ok) throw new Error('HTTP error! status: ' + response.status);
            return response.json();
        })
        .then(function(data) {
            document.getElementById('repeater-count').textContent = data.features.length;
            
            L.geoJSON(data, {
                pointToLayer: function(feature, latlng) {
                    var props = feature.properties;
                    var color = props['marker-color'] || 'blue';
                    var marker = L.marker(latlng, { icon: getMarkerIcon(color) });
                    var notes_html = props.notes.split('
').join('<br>');
                    var popupContent = '<div style="width: 250px; max-height: 300px; overflow-y: auto;"><h4 style="margin-top: 0;">' + props.name + '</h4><table style="width: 100%; font-size: 12px; border-collapse: collapse;"><tr><td style="padding: 3px; border-bottom: 1px solid #ddd;"><b>Location:</b></td><td style="padding: 3px; border-bottom: 1px solid #ddd;">' + props.location + '</td></tr><tr><td style="padding: 3px; border-bottom: 1px solid #ddd;"><b>Band:</b></td><td style="padding: 3px; border-bottom: 1px solid #ddd;">' + props.band + '</td></tr><tr><td style="padding: 3px; border-bottom: 1px solid #ddd;"><b>Channel:</b></td><td style="padding: 3px; border-bottom: 1px solid #ddd;">' + props.channel + '</td></tr><tr><td style="padding: 3px; border-bottom: 1px solid #ddd;"><b>F-in:</b></td><td style="padding: 3px; border-bottom: 1px solid #ddd;">' + props.frequency_in + ' MHz</td></tr><tr><td style="padding: 3px; border-bottom: 1px solid #ddd;"><b>F-out:</b></td><td style="padding: 3px; border-bottom: 1px solid #ddd;">' + props.frequency_out + ' MHz</td></tr><tr><td style="padding: 3px; border-bottom: 1px solid #ddd;"><b>Access:</b></td><td style="padding: 3px; border-bottom: 1px solid #ddd;">' + props.access + '</td></tr><tr><td style="padding: 3px;"><b>Notes:</b></td></tr></table><div style="font-size: 11px; padding: 5px; background: #f5f5f5; border-radius: 3px; margin-top: 5px;">' + notes_html + '</div></div>';
                    marker.bindPopup(popupContent);
                    marker._featureData = {
                        name: props.name,
                        band: props.band,
                        status: props['marker-color'] === 'red' ? 'offline' : 'online',
                        marker: marker,
                        color: color
                    };
                    allMarkers.push(marker._featureData);
                    return marker;
                }
            }).addTo(map);
            
            showAllRepeaters();
        })
        .catch(function(error) {
            console.error('Error:', error);
            document.getElementById('map').innerHTML = '<p style="padding: 20px; color: red;"><b>Error:</b> ' + error.message + '</p>';
        });
    
    var legend = L.control({position: 'bottomright'});
    legend.onAdd = function(m) {
        var div = L.DomUtil.create('div', 'legend');
        div.innerHTML = '<h4 style="margin: 0 0 10px 0;">Band Legend</h4><i style="background: #ffcc00"></i><span> HF</span><br><i style="background: #3366ff"></i><span> VHF</span><br><i style="background: #00cc44"></i><span> UHF</span><br><i style="background: #ff3333"></i><span> Offline</span>';
        return div;
    };
    legend.addTo(map);
}

function filterByBand(band) {
    currentFilter.band = band;
    applyFilter();
}

function filterByStatus(status) {
    currentFilter.status = status;
    applyFilter();
}

function applyFilter() {
    allMarkers.forEach(function(m) {
        var show = true;
        if (currentFilter.band && m.band !== currentFilter.band) show = false;
        if (currentFilter.status === 'online' && m.status === 'offline') show = false;
        if (show) map.addLayer(m.marker); else map.removeLayer(m.marker);
    });
    updateVisibleCount();
}

function showAllRepeaters() {
    currentFilter = { band: null, status: 'all' };
    allMarkers.forEach(function(m) { map.addLayer(m.marker); });
    updateVisibleCount();
}

function updateVisibleCount() {
    var count = 0;
    allMarkers.forEach(function(m) { if (map.hasLayer(m.marker)) count++; });
    document.getElementById('visible-count').textContent = count;
}

if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', initializeMap);
} else {
    initializeMap();
}
</script>

</body></html>c                  ó"   — t        t        «       y )N)ÚprintÚhtml_header© ó    ú#/var/www/html/irts/repeater_map.cgiÚgenerate_pager	   Ï   s
   € Ü	Œ+Õr   Ú__main__)ÚjsonÚsysÚosr   r   r	   Ú__name__r   r   r   ú<module>r      s=   ðó Û 
Û 	ñ Ð!Ô "ðB€òHð ˆzÒÙ…Oð r   