EtusivuLiikkeet
Hanakat LVI-liikkeiltä saat kaikki LVI-ratkaisut asennettuna. Saat yhdestä liikkeestä LVI-ratkaisut lämmitykseen, ilmanvaihtoon, kylpyhuoneisiin ja keittiöön sekä vesi- ja jätevesihuoltoon. Tarjoamme LVI-asennus- ja -huoltopalvelua ympäri Suomen, paikallisesti yli 100 liikkeen voimin.
'; infowindow.setContent(content); infowindow.open(map, this); }); } function getVisibleMarkers(map, markers) { var visibleMarkers = []; let bounds = map.getBounds(); markers.forEach(function(marker) { if(bounds.contains(marker.getPosition())) { visibleMarkers.push(marker); } }); return visibleMarkers } function initMap() { var jkl = new google.maps.LatLng(62.243903, 25.762095); infowindow = new google.maps.InfoWindow(); var map = new google.maps.Map(document.getElementById('storemap'), { mapTypeControl: false, styles: [ { featureType: 'poi', stylers: [{visibility: 'off'}] }, { featureType: 'transit', stylers: [{visibility: 'off'}] }, ] }); window.map = map; // zoom to finland var geocoder = new google.maps.Geocoder(); geocoder.geocode( { 'address': 'Finland'}, function(results, status) { if (status == google.maps.GeocoderStatus.OK) { map.setCenter(results[0].geometry.location); map.fitBounds(results[0].geometry.viewport); } }); // filter our stores listing if we have store property queryparams defined for filtering const ALLOWED_FILTERS = new Set(stores.flatMap(store => store.Properties)); const params = new URLSearchParams(window.location.search); const filters = {}; for (const [key, value] of params.entries()) { if (ALLOWED_FILTERS.has(key)) { filters[key] = value === '1' ? true : false; } } let filteredStores = Object.keys(filters).length === 0 ? stores : stores.filter(store => Object.entries(filters).every(([property, shouldInclude]) => shouldInclude ? store.Properties.includes(property) : !store.Properties.includes(property) ) ); // add all markers to map filteredStores.forEach(function(store) { // default to using saved coordinates to save cost if (parseFloat(store.Lat) && parseFloat(store.Lon)) { let res = { 'geometry': {'location': {'lat':parseFloat(store.Lat), 'lng':parseFloat(store.Lon)}}, 'name': 'store.Company', 'formatted_address': [store.Street, store.Zipcode, store.City].join(', ') } createMarker(map, res, store); } else { var service = new google.maps.places.PlacesService(map); var request = { query: store.Company + ' '+ store.City +' Finland', fields: ['name', 'geometry', 'formatted_address', 'opening_hours'], }; service.findPlaceFromQuery(request, function(results, status) { if (status === google.maps.places.PlacesServiceStatus.OK) { createMarker(map, results[0], store); } else { console.error('Maps didnt return results for: '+ store.NameOrAlias ); } }); } }); // initialize the search field var searchfield = document.getElementById('mapsearch'); var options = { types: ['geocode'], componentRestrictions: {country: 'fi'} }; autocomplete = new google.maps.places.Autocomplete(searchfield, options); // thanks: https://stackoverflow.com/a/49620828/1210837 function enableEnterKey(input) { /* Store original event listener */ const _addEventListener = input.addEventListener const addEventListenerWrapper = (type, listener) => { if (type === "keydown") { /* Store existing listener function */ const _listener = listener listener = (event) => { /* Simulate a 'down arrow' keypress if no address has been selected */ const suggestionSelected = document.getElementsByClassName('pac-item-selected').length if (event.key === 'Enter' && !suggestionSelected) { const e = new KeyboardEvent("keydown", { key: "ArrowDown", code: "ArrowDown", keyCode: 40 }); _listener.apply(input, [e]) } _listener.apply(input, [event]) } } _addEventListener.apply(input, [type, listener]) } input.addEventListener = addEventListenerWrapper } enableEnterKey(searchfield); // zoom out untill at least one marker is visible // this is not perfect but seems to do the trick // fitBounds is async and it does not have a callback (and // our code does not have a clean way of calling it either) // just wait a bit function zoomOutUntilMarkersVisible() { if (window.map.getZoom() && getVisibleMarkers(window.map, window.markers).length == 0) { // console.debug('not seeing markers, zooming out: ' + window.map.getZoom()); window.map.setZoom(window.map.getZoom()-1); setTimeout(zoomOutUntilMarkersVisible, 5); } } // if the field gets emptied zoom back to finland searchfield.addEventListener("input", function() { if(document.getElementById('mapsearch').value === "") { var geocoder = new google.maps.Geocoder(); geocoder.geocode( { 'address': 'Finland'}, function(results, status) { if (status == google.maps.GeocoderStatus.OK) { map.setCenter(results[0].geometry.location); map.fitBounds(results[0].geometry.viewport); } }); } }); // search listener autocomplete.addListener('place_changed', function() { if(window.heremarker) { window.heremarker.setMap(null); } infowindow.close(); var place = autocomplete.getPlace(); if (!place.geometry) { return; } if (place.geometry.viewport) { map.fitBounds(place.geometry.viewport); // place marker on found place window.heremarker = new google.maps.Marker({ map: map, position: place.geometry.location, title: place.name, animation: google.maps.Animation.DROP, icon: { 'url': 'https\u003A\u002F\u002Fmaps\u002Egoogle\u002Ecom\u002Fmapfiles\u002Fkml\u002Fshapes\u002Fplacemark_circle\u002Epng', 'scaledSize': new google.maps.Size(30, 30) } }); } else { map.setCenter(place.geometry.location); // place marker on found place window.heremarker = new google.maps.Marker({ map: map, position: place.geometry.location, title: place.name, animation: google.maps.Animation.DROP, icon: { 'url': 'https\u003A\u002F\u002Fmaps\u002Egoogle\u002Ecom\u002Fmapfiles\u002Fkml\u002Fshapes\u002Fplacemark_circle\u002Epng', 'scaledSize': new google.maps.Size(30, 30) } }); map.setZoom(17); // Why 17? Because it looks good. } setTimeout(zoomOutUntilMarkersVisible, 5); }); // when map is loaded and ready try to geolocate us on it google.maps.event.addListenerOnce(map, 'tilesloaded', function(){ // try to get geolocation and center the map with it if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(function(position) { var pos = { lat: position.coords.latitude, lng: position.coords.longitude }; map.setCenter(pos); map.setZoom(17); // Why 17? Because it looks good. window.heremarker = new google.maps.Marker({ map: map, position: pos, title: '', animation: google.maps.Animation.DROP, icon: { 'url': 'https\u003A\u002F\u002Fmaps\u002Egoogle\u002Ecom\u002Fmapfiles\u002Fkml\u002Fshapes\u002Fplacemark_circle\u002Epng', 'scaledSize': new google.maps.Size(30, 30) } }); setTimeout(zoomOutUntilMarkersVisible, 5); }); } }); // make sure markers are sorted function byStoreNameOrAlias(a,b) { const nameA = a.store.NameOrAlias.toUpperCase(); const nameB = b.store.NameOrAlias.toUpperCase(); let cmp = 0; if(nameA > nameB) { cmp = 1; } else if (nameA < nameB) { cmp = -1; } return cmp; } function byStoreCity(a, b) { const nameA = a.store.City.toUpperCase(); const nameB = b.store.City.toUpperCase(); let cmp = 0; if(nameA > nameB) { cmp = 1; } else if (nameA < nameB) { cmp = -1; } return cmp; } function generateIconsHTML(marker) { if (!marker.Icons || marker.Icons.length === 0) return ''; return marker.Icons.map(icon => `` ).join(''); } // when map bounds change show a list of all visible markers google.maps.event.addListener(map, 'bounds_changed', function() { // clear stores var container = document.getElementById('VisibleMarkers'); container.innerHTML = ''; let visibleMarkers = getVisibleMarkers(window.map, window.markers); visibleMarkers = visibleMarkers.sort(byStoreCity); visibleMarkers.forEach(function(marker) { var data = '
'; container.innerHTML += data; }); }); }
Mitä maksaa patteriremontti?
Laske hinta-arvio kotisi patteriremontille laskurillamme
LASKE HINTA-ARVIO