if(typeof window.contentMaps==='undefined'){window.contentMaps={};window.initialMapBounds={};} if(typeof window.bounds==='undefined'){window.bounds={};} if(typeof window.markerData==='undefined'){window.markerData={};} if(!markerData[1]){markerData[1]={};} function initMapbox_1(){mapboxgl.accessToken='pk.eyJ1IjoibGF6eXRyaXBzIiwiYSI6ImNsaTJ4anh2MTA5NDYzZW85ODJmMm45ZzcifQ.9u5pN47V7SsoFwF6_Pw5bQ';const contentMap_1=new mapboxgl.Map({container:'contentMap_1',style:'mapbox://styles/mapbox/streets-v11',center:[-122.29537250730834,47.60494077544875],zoom:5,cooperativeGestures:true});window.contentMaps[1]=contentMap_1;if(typeof window.bounds[1]==='undefined'){window.bounds[1]=new mapboxgl.LngLatBounds();} markerData[0][0]={"lonLat":["-122.693400","45.515655"],"type":"star","onClick":true,"popup":{"title":"Seattle to Portland<\/a>"},"route":{"id":"1905","color":"#0b7172"}};function getNewLngLat(map,originalLngLat,offsets){var pixel=map.project(new mapboxgl.LngLat(originalLngLat[0],originalLngLat[1]));pixel.x+=offsets.x;pixel.y+=offsets.y;return map.unproject(pixel);} Object.keys(contentMaps).forEach(function(mapNum){contentMaps[mapNum].on('zoom',function(){Object.keys(markerData[mapNum]).forEach(function(iconNum){var marker=markerData[mapNum][iconNum];if(!isMobileDevice()&&marker.cardInstance){var offsets={x:marker.card.oX,y:marker.card.oY};var newLngLat=getNewLngLat(contentMaps[mapNum],marker.lonLat,offsets);marker.cardInstance.setLngLat([newLngLat.lng,newLngLat.lat]);}});});});async function fetchRoute(d,m,i,c){const p={routeId:d};const r=await fetch('/api/request-route',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(p)});if(r.ok){const data=await r.json();if(data.response&&data.response.route){const d=JSON.parse(data.response.route);markerData[m][i].routeJson=d;updateMapWithRoute(m,i,d,c);}}} function updateMapWithRoute(m,i,r,c){const l='iconRoute_'+m+'_'+i;const g={type:'Feature',properties:{},geometry:{type:'LineString',coordinates:r}};if(contentMaps[m].getLayer(l)){contentMaps[m].setLayoutProperty(l,'visibility','visible');contentMaps[m].getSource(l).setData(g);}else{contentMaps[m].addLayer({id:l,type:'line',source:{type:'geojson',data:g},layout:{'line-join':'round','line-cap':'round'},paint:{'line-color':c,'line-width':5,'line-opacity':0.8}});}} function hideRouteLayer(m,i){const l='iconRoute_'+m+'_'+i;if(contentMaps[m].getLayer(l)){contentMaps[m].setLayoutProperty(l,'visibility','none');}} window.toggleMapIconClick=function(m,iconNum){if(markerData[m][iconNum].a){return;} for(const[key,icon]of Object.entries(markerData[m])){if(parseInt(key)===iconNum){continue;} if(icon.popupInstance){icon.popupInstance.remove();delete icon.popupInstance;} if(icon.route&&contentMaps[m].getLayer('iconRoute_'+m+'_'+key)){hideRouteLayer(m,key);} if(icon.marker){icon.marker.getElement().classList.remove('markerSpanSelect');} if(icon.cardInstance){icon.cardInstance.remove();delete icon.cardInstance;} if(icon.cardOverlay){var overlayToRemove=icon.cardOverlay;if(overlayToRemove&&overlayToRemove.parentNode){overlayToRemove.parentNode.removeChild(overlayToRemove);delete icon.cardOverlay;}} icon.a=false;} if(!markerData[m][iconNum].a){markerData[m][iconNum].marker.getElement().classList.add('markerSpanSelect');if(markerData[m][iconNum].popup){const t=markerData[m][iconNum].popup.title;const p=markerData[m][iconNum].popup.text;let popupHTML='
';if(t){popupHTML+='

'+t+'

';} if(p){popupHTML+='

'+p+'

';} popupHTML+='
';var popup=new mapboxgl.Popup({anchor:'bottom',closeButton:false,closeOnClick:false,className:'pointer'}).setLngLat(markerData[m][iconNum].lonLat).setHTML(popupHTML).addTo(contentMaps[m]);markerData[m][iconNum].popupInstance=popup;popup._content.addEventListener('click',function(){toggleMapIconClick(m,iconNum);});markerData[m][iconNum].marker.getElement().style.display='none';} if(markerData[m][iconNum].route){const layerId='iconRoute_'+m+'_'+iconNum;if(contentMaps[m].getLayer(layerId)){contentMaps[m].setLayoutProperty(layerId,'visibility','visible');}else{fetchRoute(markerData[m][iconNum].route.id,m,iconNum,markerData[m][iconNum].route.color);}} if(markerData[m][iconNum].card){var cardContent={cardTitle:markerData[m][iconNum].card.title,cardDistanceTime:markerData[m][iconNum].card.distanceTime,photoCode:markerData[m][iconNum].card.photoCode,};if(markerData[m][iconNum].hasOwnProperty('cardLink')){cardContent.cardLink=markerData[m][iconNum].cardLink;} if(markerData[m][iconNum].hasOwnProperty('cardLinkText')){cardContent.cardLinkText=markerData[m][iconNum].cardLinkText;} if(!isMobileDevice()){var cardContentHtml=createCardContentHtml(cardContent,false);var offsets={x:markerData[m][iconNum].card.oX,y:markerData[m][iconNum].card.oY};var newLngLat=getNewLngLat(contentMaps[m],markerData[m][iconNum]['lonLat'],offsets);var cardPopup=new mapboxgl.Popup({anchor:'bottom',closeButton:false,closeOnClick:false,className:'mapPopupCard'}).setHTML(cardContentHtml).setLngLat([newLngLat.lng,newLngLat.lat]).addTo(contentMaps[m]);markerData[m][iconNum].cardInstance=cardPopup;}else{var cardMobile=document.createElement('div');cardMobile.className='mapPopupCardMobile';cardMobile.innerHTML=createCardContentHtml(cardContent,true);var mapContainer=contentMaps[m].getContainer();mapContainer.appendChild(cardMobile);markerData[m][iconNum].cardOverlay=cardMobile;}} markerData[m][iconNum].a=true;updateMapBounds(m,iconNum);}else{resetMarkersAndCards(m);}} window.resetMarkersAndCards=function(m){Object.keys(markerData[m]).forEach((i)=>{if(markerData[m][i].marker){markerData[m][i].marker.getElement().classList.remove('markerSpanSelect');} if(markerData[m][i].popupInstance){markerData[m][i].popupInstance.remove();delete markerData[m][i].popupInstance;} if(markerData[m][i].route){if(contentMaps[m].getLayer('iconRoute_'+m+'_'+i)){hideRouteLayer(m,i);}} if(markerData[m][i].card){if(markerData[m][i].cardInstance){markerData[m][i].cardInstance.remove();delete markerData[m][i].cardInstance;}} if(markerData[m][i].cardOverlay){var overlayToRemove=markerData[m][i].cardOverlay;if(overlayToRemove&&overlayToRemove.parentNode){overlayToRemove.parentNode.removeChild(overlayToRemove);delete markerData[m][i].cardOverlay;}} markerData[m][i].marker.getElement().style.display='block';markerData[m][i].a=false;if(markerData[m][i].best){updateMapBounds(m,i);}});} function createCardContentHtml(c,m){let htmlContent='
';if(c.photoCode){htmlContent+='
'+c.photoCode+'
';} if(c.cardTitle||c.cardDistanceTime||c.cardLink){htmlContent+='
';if(c.cardTitle){htmlContent+='
'+c.cardTitle+'
';} if(c.cardDistanceTime){if(m){const parts=c.cardDistanceTime.split('⏱️');htmlContent+='
'+parts[0].trim()+'
⏱️ '+parts[1].trim()+'
';}else{htmlContent+='
'+c.cardDistanceTime+'
';}} if(c.cardLink){var linkText=c.cardLinkText||'Read more';htmlContent+='
'+linkText+'';} htmlContent+='
';} htmlContent+='
';return htmlContent;} $(document).on('shown.bs.modal','[id^=contentMapModal_]',function(){let modalId=$(this).attr('id');let mapNum=modalId.replace('contentMapModal_','');if(window.contentMaps&&window.contentMaps[mapNum]){window.contentMaps[mapNum].resize();Object.keys(markerData[mapNum]).forEach((i)=>{updateMapBounds(mapNum,i);});}});$(document).on('hidden.bs.modal','[id^=contentMapModal_]',function(){resetMarkersAndCards($(this).attr('id').replace('contentMapModal_',''));});function isMobileDevice(){return window.innerWidth<=768||window.innerHeight<=600;} function updateMapBounds(mapNum,iconNum){const oldBounds=contentMaps[mapNum].getBounds();const newBounds=contentMaps[mapNum].getBounds();const mapDimensions=contentMaps[mapNum].getContainer().getBoundingClientRect();const clickedMarker=markerData[mapNum][iconNum];const lngDiff=oldBounds.getNorthEast().lng-oldBounds.getSouthWest().lng;const latDiff=oldBounds.getNorthEast().lat-oldBounds.getSouthWest().lat;const lngPerPx=lngDiff / mapDimensions.width;const latPerPx=latDiff / mapDimensions.height;if(clickedMarker['popup']&&clickedMarker.a){const pixelCoordinates=contentMaps[mapNum].project(clickedMarker.lonLat);const tooCloseX=100;const tooCloseT=80;const tooCloseB=10;const eXp=120;const eTp=120;const eBp=20;const extendNWSE=[0,0,0,0];if(pixelCoordinates.xmapDimensions.width-tooCloseX){extendNWSE[1]=eXp-(mapDimensions.width-pixelCoordinates.x);} if(pixelCoordinates.ymapDimensions.height-tooCloseB){extendNWSE[2]=eBp-(mapDimensions.height-pixelCoordinates.y);} for(let i=0;i0){switch(i){case 0:const extendNorthLat=extendNWSE[i]*latPerPx;newBounds.extend(new mapboxgl.LngLat(clickedMarker.lonLat[0],oldBounds.getNorthEast().lat+extendNorthLat));break;case 1:const extendEastLng=extendNWSE[i]*lngPerPx;newBounds.extend(new mapboxgl.LngLat(oldBounds.getNorthEast().lng+extendEastLng,clickedMarker.lonLat[1]));break;case 2:const extendSouthLat=extendNWSE[i]*latPerPx;newBounds.extend(new mapboxgl.LngLat(clickedMarker.lonLat[0],oldBounds.getSouthWest().lat-extendSouthLat));break;case 3:const extendWestLng=extendNWSE[i]*lngPerPx;newBounds.extend(new mapboxgl.LngLat(oldBounds.getSouthWest().lng-extendWestLng,clickedMarker.lonLat[1]));break;}}} if(Math.abs(newBounds.getSouthWest().lng-oldBounds.getSouthWest().lng)>1e-6||Math.abs(newBounds.getSouthWest().lat-oldBounds.getSouthWest().lat)>1e-6||Math.abs(newBounds.getNorthEast().lng-oldBounds.getNorthEast().lng)>1e-6||Math.abs(newBounds.getNorthEast().lat-oldBounds.getNorthEast().lat)>1e-6){contentMaps[mapNum].fitBounds(newBounds,{padding:0,duration:600,easing:(t)=>t*(2-t)});}} if(clickedMarker['route']&&clickedMarker['routeJson']&&clickedMarker['clicked']){const paddingRoutePixels=20;let extendWest=false,extendEast=false,extendNorth=false,extendSouth=false;clickedMarker['routeJson'].forEach(coord=>{if(coord[0]newBounds.getEast())extendEast=true;if(coord[1]>newBounds.getNorth())extendNorth=true;if(coord[1]t*(2-t)});} if(!isMobileDevice()&&markerData[mapNum][iconNum].card&&markerData[mapNum][iconNum].a){const w=300;const h=360;const p=100;const oX=markerData[mapNum][iconNum].card.oX;const oY=markerData[mapNum][iconNum].card.oY;const markerPixel=contentMaps[mapNum].project(clickedMarker.lonLat);const topLeftPixel={x:markerPixel.x+oX-w/2-p,y:markerPixel.y+oY-h-p};const topRightPixel={x:topLeftPixel.x+w+(2*p),y:topLeftPixel.y};const bottomLeftPixel={x:topLeftPixel.x,y:topLeftPixel.y+h+(2*p)};const bottomRightPixel={x:topRightPixel.x,y:bottomLeftPixel.y};[topLeftPixel,topRightPixel,bottomLeftPixel,bottomRightPixel].forEach(pixel=>{const lngLat=contentMaps[mapNum].unproject(pixel);newBounds.extend(lngLat);});contentMaps[mapNum].fitBounds(newBounds,{padding:0,duration:600,easing:(t)=>t*(2-t)});}}markerData[0][1]={"lonLat":["-123.319086","47.502871"],"type":"star","onClick":true,"popup":{"title":"Seattle to Olympic National Park<\/a>"},"route":{"id":"1906","color":"#0b7172"}};markerData[0][2]={"lonLat":["-124.105547","46.887737"],"type":"star","onClick":true,"popup":{"title":"Seattle to Westport, Washington<\/a>"},"route":{"id":"1907","color":"#0b7172"}};markerData[0][3]={"lonLat":["-121.919351","46.752038"],"type":"star","onClick":true,"popup":{"title":"Seattle to Mt Rainier<\/a>"},"route":{"id":"1908","color":"#0b7172"}};markerData[0][4]={"lonLat":["-121.837972","47.543368"],"type":"star","onClick":true,"popup":{"title":"Seattle to Snoqualmie Falls<\/a>"},"route":{"id":"1909","color":"#0b7172"}};markerData[0][5]={"lonLat":["-120.545599","46.993730"],"type":"star","onClick":true,"popup":{"title":"Seattle to Ellensburg<\/a>"},"route":{"id":"1910","color":"#0b7172"}};markerData[0][6]={"lonLat":["-120.669218","47.599619"],"type":"star","onClick":true,"popup":{"title":"Seattle to Leavenworth<\/a>"},"route":{"id":"1911","color":"#0b7172"}};markerData[0][7]={"lonLat":["-122.619346","48.514983"],"type":"star","onClick":true,"popup":{"title":"Seattle to San Juan Islands<\/a>"},"route":{"id":"1912","color":"#0b7172"}};markerData[0][8]={"lonLat":["-122.914583","50.115919"],"type":"star","onClick":true,"popup":{"title":"Seattle to Whistler, BC<\/a>"},"route":{"id":"1913","color":"#0b7172"}};markerData[0][9]={"lonLat":["-121.754338","45.710499"],"type":"star","onClick":true,"popup":{"title":"Seattle to Columbia River Gorge<\/a>"},"route":{"id":"1914","color":"#0b7172"}};markerData[0][10]={"lonLat":["-123.121699","49.285914"],"type":"star","onClick":true,"popup":{"title":"Seattle to Vancouver<\/a>"},"route":{"id":"1915","color":"#0b7172"}};markerData[0][11]={"lonLat":["-122.440378","47.998965"],"type":"star","onClick":true,"popup":{"title":"Seattle to Whidbey Island<\/a>"},"route":{"id":"1916","color":"#0b7172"}};markerData[0][12]={"lonLat":["-120.348700","48.030254"],"type":"star","onClick":true,"popup":{"title":"Seattle to North Cascades and Lake Chelan<\/a>"},"route":{"id":"1917","color":"#0b7172"}};markerData[0][13]={"lonLat":["-124.045047","46.354611"],"type":"star","onClick":true,"popup":{"title":"Seattle to Long Beach, Washington<\/a>"},"route":{"id":"1918","color":"#0b7172"}};markerData[0][14]={"lonLat":["-110.601082","44.472644"],"type":"star","onClick":true,"popup":{"title":"Seattle to Yellowstone National Park<\/a>"},"route":{"id":"1919","color":"#0b7172"}};markerData[0][15]={"lonLat":["-118.341423","46.070888"],"type":"star","onClick":true,"popup":{"title":"Seattle to Walla Walla<\/a>"},"route":{"id":"1920","color":"#0b7172"}};markerData[0][16]={"lonLat":["-113.789216","48.707304"],"type":"star","onClick":true,"popup":{"title":"Seattle to Glacier National Park<\/a>"},"route":{"id":"1921","color":"#0b7172"}};markerData[0][17]={"lonLat":["-116.781936","47.657607"],"type":"star","onClick":true,"popup":{"title":"Seattle to Coeur d'Alene, Idaho<\/a>"},"route":{"id":"1922","color":"#0b7172"}};markerData[0][18]={"lonLat":["-123.855315","39.260667"],"type":"star","onClick":true,"popup":{"title":"Seattle to Mendocino, CA<\/a>"},"route":{"id":"1923","color":"#0b7172"}};markerData[0][19]={"lonLat":["-120.017521","39.095015"],"type":"star","onClick":true,"popup":{"title":"Seattle to Lake Tahoe<\/a>"},"route":{"id":"1924","color":"#0b7172"}};initialMapBounds[1]=new mapboxgl.LngLatBounds(window.bounds[1].getSouthWest(),window.bounds[1].getNorthEast());const visibleMapRoutes_1=[];contentMaps[1].on('click',(e)=>{resetMarkersAndCards(1);});const markerConfig={'finish':{className:'marker_finish',size:[58,58],offset:[0,-29],span:false,best:false,text:false,},'start':{className:'marker_start',size:[58,58],offset:[0,-29],span:false,best:false,text:false,},'star':{className:'marker_star',size:[58,58],offset:[0,-29],span:false,best:false,text:false,},'numbered':{className:'mapMarkerNum',size:false,offset:[0,0],span:true,best:true,text:false,},'star-plain':{className:'mapMarkerNum markerSpanRed',size:false,offset:[0,0],span:true,best:false,text:'☆',},'grey':{className:'mapMarkerNum markerSpanGrey',size:false,offset:[0,0],span:true,best:false,text:false,},};function addMarkersToMap(m,f=null){Object.values(markerData[m]).forEach((i,n)=>{if(f!==null&&n'+t+'';} if(mC.width&&mC.height){el.style.width=mC.width+'px';el.style.height=mC.height+'px';} var marker=new mapboxgl.Marker(el,{offset:mC.offset}).setLngLat(i.lonLat).addTo(window.contentMaps[m]);marker.markerType=i.iconType;if(f!==null){} i.marker=marker;if(i.best){window.bounds[m].extend(i.lonLat);} if(i.onClick){marker.getElement().addEventListener('click',function(){event.stopPropagation();toggleMapIconClick(m,n);});}});} addMarkersToMap(1);contentMap_1.fitBounds(window.bounds[1],{padding:{top:60,bottom:60,left:60,right:60}});} var mapScriptCreated = 0; var mapCssCreated = 0; var mapScriptLoaded = 0; var mapCssLoaded = 0; var mapLoadList = []; function showLazyMap(fname) { if (mapScriptLoaded == 1 && mapCssLoaded == 1) { if (!mapLoadList.includes(fname)) { window[fname](); mapLoadList.push(fname); } } } (function fn() { var pics = document.querySelectorAll('.no-js-hide'); pics.forEach(function(pic) { pic.classList.toggle('no-js-hide'); }); var lazyImages = [].slice.call(document.querySelectorAll(".lazeeload")); if ("IntersectionObserver" in window) { const config = { root: null, rootMargin: '1000px', threshold: 0 }; let lazyImageObserver = new IntersectionObserver(function(entries, observer) { entries.forEach(function(entry) { if (entry.isIntersecting) { let lazyImage = entry.target; if (lazyImage.dataset.src) {lazyImage.src = lazyImage.dataset.src;} if (lazyImage.dataset.srcset) {lazyImage.srcset = lazyImage.dataset.srcset;} if (lazyImage.dataset.map) { const fname = "initMapbox_"+lazyImage.dataset.map; if (mapScriptLoaded == 0) { let script = document.createElement('script'); script.async=true; script.defer=true; script.src = "https://api.mapbox.com/mapbox-gl-js/v3.0.0/mapbox-gl.js"; script.onload = function(){ mapScriptLoaded = 1; showLazyMap(fname); } document.head.appendChild(script); mapScriptCreated = 1; let css = document.createElement('link'); css.rel = "stylesheet"; css.href = "https://api.mapbox.com/mapbox-gl-js/v3.0.0/mapbox-gl.css"; css.onload = function(){ mapCssLoaded = 1; showLazyMap(fname); } document.head.appendChild(css); mapCssCreated = 1; } else { if (typeof window[fname] === 'function') { window[fname](); } showLazyMap(fname); } } lazyImage.classList.remove("no-js-hide"); lazyImage.classList.remove("lazeeload"); lazyImageObserver.unobserve(lazyImage); } }); }, config); lazyImages.forEach(function(lazyImage) { lazyImageObserver.observe(lazyImage); lazyImage.classList.add("lazeeload-activated"); }); } else { let active = false; const lazyLoad = function() { if (active === false) { active = true; setTimeout(function() { lazyImages.forEach(function(lazyImage) { if ((lazyImage.getBoundingClientRect().top <= window.innerHeight+1000 && lazyImage.getBoundingClientRect().bottom >= 0) && getComputedStyle(lazyImage).display !== "none") { if (lazyImage.dataset.src) lazyImage.src = lazyImage.dataset.src; if (lazyImage.dataset.srcset) lazyImage.srcset = lazyImage.dataset.srcset; if (lazyImage.dataset.onload) lazyImage.onload = lazyImage.dataset.onload; lazyImage.classList.remove("lazeeload"); lazyImages = lazyImages.filter(function(image) { return image !== lazyImage; }); if (lazyImages.length === 0) { document.removeEventListener("scroll", lazyLoad); window.removeEventListener("resize", lazyLoad); window.removeEventListener("orientationchange", lazyLoad); } } }); active = false; }, 200); } }; document.addEventListener("scroll", lazyLoad); window.addEventListener("resize", lazyLoad); window.addEventListener("orientationchange", lazyLoad); } var lazyImages = [].slice.call(document.querySelectorAll(".lazeeload")); i=1; lazyImages.forEach(function(lazyImage) { if (!(lazyImage.classList.contains("lazeeload-activated"))) { if (lazyImage.dataset.src) lazyImage.src = lazyImage.dataset.src; if (lazyImage.dataset.srcset) lazyImage.srcset = lazyImage.dataset.srcset; lazyImage.classList.remove("lazeeload"); } }); })();