Hanksugi Tire — logotipo van de Pegaso
  • Inicio
  • Producten
      Catalogus Nederland Ultra Premium Banden de Aandrijving Banden de Stuur Alle Posición
  • Technologie
  • Loopvlakvernieuwing
  • Bronnen
      Kostencalculator' + '
'; marker.bindPopup(popupContent, { maxWidth: 300 }); marker.on('click', function() { highlightDealer(index); }); markers.push(marker); }); // Fit map to show all markers if (markers.length > 0) { var group = L.featureGroup(markers); map.fitBounds(group.getBounds().pad(0.15)); } // Make map accessible for debugging window._hkMap = map; window._hkMarkers = markers; // Haversine distance in km function haversineMiles(lat1, lng1, lat2, lng2) { var R = 6371; var toRad = function(x) { return x * Math.PI / 180; }; var dLat = toRad(lat2 - lat1); var dLng = toRad(lng2 - lng1); var a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * Math.sin(dLng/2) * Math.sin(dLng/2); return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); } // ZIP geocoding via zippopotam.us (free, no key, CORS-enabled) function geocodeZip(zip) { return fetch('https://api.zippopotam.us/us/' + zip) .then(function(r) { if (!r.ok) throw new Error('ZIP not found'); return r.json(); }) .then(function(data) { if (!data.places || !data.places.length) throw new Error('No coordinates'); var p = data.places[0]; return { lat: parseFloat(p.latitude), lng: parseFloat(p.longitude), city: p['place name'], state: p['state abbreviation'] }; }); } // Search location marker + state var searchMarker = null; var searchOrigin = null; // Render dealer cards in sidebar function renderDealers(filteredDealers) { var list = document.getElementById('dealerList'); if (!filteredDealers || filteredDealers.length === 0) { list.innerHTML = '

No se encontraron distribuidores.
Intente con otro término de búsqueda o estado.

'; return; } list.innerHTML = ''; filteredDealers.forEach(function(item) { var dealer = item.dealer || item; var idx = item.index !== undefined ? item.index : dealers.indexOf(dealer); var card = document.createElement('div'); card.className = 'dealer-card'; card.setAttribute('data-index', idx); var distanceHtml = ''; if (typeof item.distance === 'number') { distanceHtml = '
' + item.distance.toFixed(1) + ' km
'; } card.innerHTML = distanceHtml + '

' + dealer.name + '

' + '

' + dealer.city + ', ' + dealer.state + ' ' + dealer.zip + '

' + '

' + dealer.phone + '

'; card.addEventListener('click', function() { map.setView([dealer.lat, dealer.lng], 12); markers[idx].openPopup(); highlightDealer(idx); }); list.appendChild(card); }); } function highlightDealer(index) { document.querySelectorAll('.dealer-card').forEach(function(card) { card.classList.remove('active'); if (parseInt(card.getAttribute('data-index')) === index) { card.classList.add('active'); card.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); } }); // Reset all markers then highlight the active one markers.forEach(function(m, i) { if (i === index) { m.setStyle({ radius: 14, fillColor: '#8B0000', weight: 3 }); } else { m.setStyle({ radius: 10, fillColor: '#C41E3A', weight: 2 }); } }); } // Initial render renderDealers(dealers.map(function(d, i) { return { dealer: d, index: i }; })); // Clear any prior search origin marker + reset sort function clearSearchOrigin() { if (searchMarker) { map.removeLayer(searchMarker); searchMarker = null; } searchOrigin = null; } // Render results sorted by distance from a given lat/lng function renderByDistance(origin, stateFilter) { var results = dealers.map(function(d, i) { return { dealer: d, index: i, distance: haversineMiles(origin.lat, origin.lng, d.lat, d.lng) }; }).filter(function(item) { return !stateFilter || item.dealer.state === stateFilter; }).sort(function(a, b) { return a.distance - b.distance; }); renderDealers(results); if (results.length > 0) { // Show search origin marker if (searchMarker) map.removeLayer(searchMarker); searchMarker = L.marker([origin.lat, origin.lng], { icon: L.divIcon({ className: 'search-origin-marker', html: '
', iconSize: [28, 28], iconAnchor: [14, 14] }) }).addTo(map); searchMarker.bindPopup('Su ubicación
' + (origin.city ? origin.city + ', ' + origin.state : 'Punto personalizado')); // Fit bounds to origin + nearest 5 dealers var nearest = results.slice(0, 5); var bounds = L.latLngBounds([[origin.lat, origin.lng]].concat(nearest.map(function(item) { return [item.dealer.lat, item.dealer.lng]; }))); map.fitBounds(bounds, { padding: [60, 60], maxZoom: 10 }); } } // Text search (non-ZIP) function textSearch(query, stateFilter) { var results = dealers.map(function(d, i) { return { dealer: d, index: i }; }).filter(function(item) { var d = item.dealer; var matchesState = !stateFilter || d.state === stateFilter; var matchesQuery = !query || d.name.toLowerCase().includes(query) || d.city.toLowerCase().includes(query) || d.state.toLowerCase().includes(query) || d.zip.includes(query) || d.address.toLowerCase().includes(query); return matchesState && matchesQuery; }); renderDealers(results); if (results.length > 0) { var bounds = L.latLngBounds(results.map(function(item) { return [item.dealer.lat, item.dealer.lng]; })); map.fitBounds(bounds, { padding: [50, 50], maxZoom: 10 }); } } // Search functionality — detects 5-digit ZIP and geocodes it function searchDealers() { var query = document.getElementById('dealerSearch').value.trim(); var stateFilter = document.getElementById('stateFilter').value; var btn = document.getElementById('dealerSearchBtn'); if (/^\d{5}$/.test(query)) { // ZIP code path: geocode + sort by distance btn.innerHTML = ''; btn.disabled = true; geocodeZip(query) .then(function(origin) { searchOrigin = origin; renderByDistance(origin, stateFilter); }) .catch(function(err) { clearSearchOrigin(); // Fall back to substring match on ZIP textSearch(query.toLowerCase(), stateFilter); }) .then(function() { btn.innerHTML = ''; btn.disabled = false; }); } else { clearSearchOrigin(); textSearch(query.toLowerCase(), stateFilter); } } document.getElementById('dealerSearchBtn').addEventListener('click', searchDealers); document.getElementById('dealerSearch').addEventListener('keyup', function(e) { if (e.key === 'Enter') searchDealers(); }); document.getElementById('stateFilter').addEventListener('change', searchDealers); // Set initial view to continental US map.setView([38.5, -96.0], 4); });