@tailwind base;
@tailwind components;
@tailwind utilities;
@font-face {
font-family: 'PublicSans';
src: url('/fonts/Public_Sans/static/PublicSans-Regular.ttf') format('truetype');
}
html {
font-family: PublicSans, sans-serif;
}
::selection {
color: black;
background: #eaf2ff;
}
:fullscreen {
background-color:pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888 } /* Comment */
.highlight .err { color: #A61717; background-color: #E3D2D2 } /* Error */
.highlight .k { color: #080; font-weight: bold } /* Keyword */
.highlight .ch { color: #888 } /* Comment.Hashbang */
.highlight .cm { color: #888 } /* Comment.Multiline */
.highlight .cp { color: #C00; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888 } /* Comment.Single */
.highlight .cs { color: #C00; font-weight: bold; background-color: #FFF0F0 } /* Comment.Special */
.highlight .gd { color: #000; background-color: #FDD } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #A00 } /* Generic.Error */
.highlight .gh { color: #333 } /* Generic.Heading */
.highlight .gi { color: #000; background-color: #DFD } /* Generic.Inserted */
.highlight .go { color: #888 } /* Generic.Output */
.highlight .gp { color: #555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666 } /* Generic.Subheading */
.highlight .gt { color: #A00 } /* Generic.Traceback */
.highlight .kc { color: #080; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #080; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #080; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #080 } /* Keyword.Pseudo */
.highlight .kr { color: #080; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #00D; font-weight: bold } /* Literal.Number */
.highlight .s { color: #D20; background-color: #FFF0F0 } /* Literal.String */
.highlight .na { color: #369 } /* Name.Attribute */
.highlight .nb { color: #038 } /* Name.Builtin */
.highlight .nc { color: #B06; font-weight: bold } /* Name.Class */
.highlight .no { color: #036; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555 } /* Name.Decorator */
.highlight .ne { color: #B06; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #06B; font-weight: bold } /* Name.Function */
.highlight .nl { color: #369; font-style: italic } /* Name.Label */
.highlight .nn { color: #B06; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #369; font-weight: bold } /* Name.Property */
.highlight .nt { color: #B06; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #369 } /* Name.Variable */
.highlight .ow { color: #080 } /* Operator.Word */
.highlight .w { color: #BBB } /* Text.Whitespace */
.highlight .mb { color: #00D; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #00D; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #00D; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #00D; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #00D; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #D20; background-color: #FFF0F0 } /* Literal.String.Affix */
.highlight .sb { color: #D20; background-color: #FFF0F0 } /* Literal.String.Backtick */
.highlight .sc { color: #D20; background-color: #FFF0F0 } /* Literal.String.Char */
.highlight .dl { color: #D20; background-color: #FFF0F0 } /* Literal.String.Delimiter */
.highlight .sd { color: #D20; background-color: #FFF0F0 } /* Literal.String.Doc */
.highlight .s2 { color: #D20; background-color: #FFF0F0 } /* Literal.String.Double */
.highlight .se { color: #04D; background-color: #FFF0F0 } /* Literal.String.Escape */
.highlight .sh { color: #D20; background-color: #FFF0F0 } /* Literal.String.Heredoc */
.highlight .si { color: #33B; background-color: #FFF0F0 } /* Literal.String.Interpol */
.highlight .sx { color: #2B2; background-color: #F0FFF0 } /* Literal.String.Other */
.highlight .sr { color: #080; background-color: #FFF0FF } /* Literal.String.Regex */
.highlight .s1 { color: #D20; background-color: #FFF0F0 } /* Literal.String.Single */
.highlight .ss { color: #A60; background-color: #FFF0F0 } /* Literal.String.Symbol */
.highlight .bp { color: #038 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #06B; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #369 } /* Name.Variable.Class */
.highlight .vg { color: #D70 } /* Name.Variable.Global */
.highlight .vi { color: #33B } /* Name.Variable.Instance */
.highlight .vm { color: #369 } /* Name.Variable.Magic */
.highlight .il { color: #00D; font-weight: bold } /* Literal.Number.Integer.Long */<script>
export let locations;
import { onMount, onDestroy } from 'svelte';
import { browser } from '$app/environment';
import html2canvas from 'html2canvas';
function captureHighResMap(mapElement, scale = 2) {
// Backup original size
let originalWidth = mapElement.offsetWidth;
let originalHeight = mapElement.offsetHeight;
// Scale the map element
mapElement.style.transform = `scale(${scale})`;
mapElement.style.transformOrigin = 'top left';
mapElement.style.width = originalWidth * scale + 'px';
mapElement.style.height = originalHeight * scale + 'px';
return html2canvas(mapElement, {
width: originalWidth * scale,
height: originalHeight * scale,
scale: scale
}).then((canvas) => {
// Restore the original size
mapElement.style.transform = '';
mapElement.style.width = originalWidth + 'px';
mapElement.style.height = originalHeight + 'px';
return canvas;
});
}
let mapElement;
let map;
function updateLabelVisibility() {
const zoom = map.getZoom();
map.eachLayer((layer) => {
if (layer.getTooltip) {
const tooltip = layer.getTooltip();
if (tooltip) {
if (zoom > 14) {
// Show labels at zoom levels greater than 14
tooltip.setOpacity(1.0);
} else {
tooltip.setOpacity(0.0);
}
}
}
});
}
onMount(async () => {
if (browser) {
const L = await import('leaflet');
map = L.map(mapElement, {
zoomSnap: 0,
attributionControl: false
}).setView([49.26, -123.05], 12);
const myCustomColour = '#F7931A';
const markerHtmlStyles = `
background-color: ${myCustomColour};
width: 1.2rem;
height: 1.2rem;
display: block;
position: relative;
border-radius: 100% 100% 0;
transform: rotate(45deg);
opacity: 0.9;
border: 1px solid #666`;
const icon = L.divIcon({
className: 'my-custom-pin',
iconAnchor: [0, 24],
labelAnchor: [-6, 0],
popupAnchor: [0, -36],
html: `<span style="${markerHtmlStyles}" />`
});
locations = locations.filter(
(location) =>
location['osm_json'].tags &&
location['osm_json'].tags['payment:coinos'] === 'yes' &&
location['osm_json'].lat &&
location['osm_json'].lon
);
L.tileLayer('https://stamen-tiles-{s}.a.ssl.fastly.net/toner/{z}/{x}/{y}.png', {
maxZoom: 18,
subdomains: ['a', 'b', 'c', 'd']
}).addTo(map);
const checkAddress = (location) => {
if (location['addr:housenumber'] && location['addr:street'] && location['addr:city']) {
return `${
location['addr:housenumber'] +
' ' +
location['addr:street'] +
', ' +
location['addr:city']
}`;
} else if (location['addr:street'] && location['addr:city']) {
return `${location['addr:street'] + ', ' + location['addr:city']}`;
} else if (location['addr:city']) {
return `${location['addr:city']}`;
} else {
return '';
}
};
locations.forEach((location) => {
if (location['deleted_at']) return;
location = location['osm_json'];
let marker = L.marker([location.lat, location.lon], { icon });
if (location.tags && location.tags.name) {
marker.bindTooltip(location.tags.name, { permanent: true }).openTooltip();
}
marker.bindPopup(
`${
location.tags && location.tags.name
? `<span class='block'>${location.tags.name}</span>`
: ''
}
<span class='block'>${location.tags && checkAddress(location.tags)}</span>
${
location.tags && location.tags.phone
? `<a href='tel:${location.tags.phone}' class='block'>${location.tags.phone}</a>`
: ''
}
${
location.tags && location.tags.website
? `<a href=${location.tags.website} target="_blank" rel="noreferrer" class='block'>${location.tags.website}</a>`
: ''
}
${
location.tags && location.tags['contact:twitter']
? `<a href=${
location.tags['contact:twitter'].startsWith('http')
? location.tags['contact:twitter']
: `https://twitter.com/${location.tags['contact:twitter']}`
} target="_blank" rel="noreferrer" class='block'>TWT: ${
location.tags['contact:twitter']
}</a>`
: ''
}
${
location.tags && location.tags['contact:instagram']
? `<a href=${
location.tags['contact:instagram'].startsWith('http')
? location.tags['contact:instagram']
: `https://instagram.com/${location.tags['contact:instagram']}`
} target="_blank" rel="noreferrer" class='block'>IG: ${
location.tags['contact:instagram']
}</a>`
: ''
}
${
location.tags && location.tags['contact:facebook']
? `<a href=${
location.tags['contact:facebook'].startsWith('http')
? location.tags['contact:facebook']
: `https://facebook.com/${location.tags['contact:facebook']}`
} target="_blank" rel="noreferrer" class='block'>FB: ${
location.tags['contact:facebook']
}</a>`
: ''
}
${
location.tags && location.tags['contact:linkedin']
? `<a href=${
location.tags['contact:linkedin'].startsWith('http')
? location.tags['contact:linkedin']
: `https://linkedin.com/${location.tags['contact:linkedin']}`
} target="_blank" rel="noreferrer" class='block'>LI: ${
location.tags['contact:linkedin']
}</a>`
: ''
}`
);
marker.addTo(map);
});
updateLabelVisibility();
map.on('zoomend', updateLabelVisibility);
// map.fitBounds(locations.map(({ osm_json: { lat, lon } }) => [lat, lon]));
}
});
onDestroy(async () => {
if (map) {
map.off('zoomend', updateLabelVisibility);
map.remove();
}
});
</script>
<div class="container mx-auto max-w-4xl">
<div class="flex w-full">
<div class="mx-auto h-[550px] w-full z-0" bind:this={mapElement} />
</div>
</div>
<style>
@import 'leaflet/dist/leaflet.css';
:global(.leaflet-tooltip) {
border: none;
border-radius: 4px;
font-size: 12px;
font-weight: bolder;
color: black;
background-color: rgba(255, 255, 255, 0.9);
left: 1.3rem;
top: -1rem;
}
</style>