aboutsummaryrefslogtreecommitdiffstats
path: root/src/components
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2023-10-05 22:15:05 -0700
committerAdam Soltys <[email protected]>2023-10-05 22:15:09 -0700
commit5dcd48afc84eee277156fbf291ccc3c0191df0f3 (patch)
tree719d58d787160633c07df2b5d6d295f862ad9926 /src/components
parentb8a7b833ca47d3f614cd285f557dcd2d04b6966e (diff)
downloadcoinos-ui-5dcd48afc84eee277156fbf291ccc3c0191df0f3.tar.gz
coinos-ui-5dcd48afc84eee277156fbf291ccc3c0191df0f3.zip
map update
Diffstat (limited to 'src/components')
-rw-r--r--src/components/LocationsMap.svelte277
1 files changed, 90 insertions, 187 deletions
diff --git a/src/components/LocationsMap.svelte b/src/components/LocationsMap.svelte
index 76523006..c4facf21 100644
--- a/src/components/LocationsMap.svelte
+++ b/src/components/LocationsMap.svelte
@@ -1,230 +1,133 @@
<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;
+ import 'maplibre-gl/dist/maplibre-gl.css';
- // 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';
+ export let locations;
+ let map;
+ let mapContainer;
+ let markers = [];
- 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';
+ let 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 '';
+ }
+ };
- return canvas;
- });
- }
+ function updateLabelVisibility() {
+ if (!map) return;
+ let zoom = map.getZoom();
+ let bounds = map.getBounds();
- let mapElement;
- let map;
+ for (let marker of markers) {
+ let isInView = bounds.contains(marker.getLngLat());
+ let popup = marker.getPopup();
+ let { tags } = marker;
- 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);
- }
- }
+ if (zoom > 13 && isInView) {
+ popup.setHTML(`<span class='block font-bold'>${tags.name}</span>`).addTo(map);
+ } else {
+ popup.remove();
+ popup.setHTML(html(tags));
}
- });
+ }
}
- 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);
+ let html = (tags) => `${
+ tags && tags.name ? `<span class='block font-bold'>${tags.name}</span>` : ''
+ }
- 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 '';
- }
- };
+ <span class='block'>${tags && checkAddress(tags)}</span>
- locations.forEach((location) => {
- if (location['deleted_at']) return;
+ ${tags && tags.phone ? `<a href='tel:${tags.phone}' class='block'>${tags.phone}</a>` : ''}
- location = location['osm_json'];
- let marker = L.marker([location.lat, location.lon], { icon });
+ ${
+ tags && tags.website
+ ? `<a href=${tags.website} target="_blank" rel="noreferrer" class='block text-blue-400'>${tags.website}</a>`
+ : ''
+ }`;
- if (location.tags && location.tags.name) {
- marker.bindTooltip(location.tags.name, { permanent: true }).openTooltip();
- }
+ onMount(() => {
+ if (browser) {
+ import('maplibre-gl').then(({ default: maplibre }) => {
+ map = new maplibre.Map({
+ container: mapContainer,
+ style: 'https://tiles.stadiamaps.com/styles/stamen_toner.json',
+ center: [-123.05, 49.26],
+ zoom: 10.5
+ });
- marker.bindPopup(
- `${
- location.tags && location.tags.name
- ? `<span class='block'>${location.tags.name}</span>`
- : ''
- }
+ map.on('load', () => {
+ locations.forEach((location) => {
+ if (location['deleted_at']) return;
- <span class='block'>${location.tags && checkAddress(location.tags)}</span>
+ let { lat, lon, tags } = location['osm_json'];
- ${
- location.tags && location.tags.phone
- ? `<a href='tel:${location.tags.phone}' class='block'>${location.tags.phone}</a>`
- : ''
- }
+ let element = document.createElement('div');
+ element.className = 'marker';
- ${
- location.tags && location.tags.website
- ? `<a href=${location.tags.website} target="_blank" rel="noreferrer" class='block'>${location.tags.website}</a>`
- : ''
- }
+ let marker = new maplibre.Marker({ color: '#F7931A' })
+ .setLngLat([lon, lat])
+ .setPopup(new maplibre.Popup().setHTML(html(tags)))
+ .addTo(map);
- ${
- 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>`
- : ''
- }
+ marker.getElement().addEventListener('click', () => {
+ let h = html(marker.tags);
+ let popup = marker.getPopup();
+ popup.setHTML(h);
+ });
- ${
- 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>`
- : ''
- }
+ marker.tags = tags;
- ${
- 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>`
- : ''
- }
+ markers.push(marker);
+ });
- ${
- 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('moveend', updateLabelVisibility);
+ map.on('zoomend', updateLabelVisibility);
+ });
});
-
- 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();
- }
+ onDestroy(() => {
+ if (map) {
+ map.off('moveend', updateLabelVisibility);
+ 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 class="mx-auto h-[550px] w-full z-0" bind:this={mapContainer} />
</div>
</div>
<style>
- @import 'leaflet/dist/leaflet.css';
+ :global(.maplibregl-popup-close-button) {
+ font-size: 18px;
+ padding: 8px;
+ }
- :global(.leaflet-tooltip) {
- border: none;
+ :global(.maplibregl-popup-content) {
+ padding: 0.5em 1em;
+ border: 1px solid black;
border-radius: 4px;
- font-size: 12px;
- font-weight: bolder;
+ font-size: 14px;
color: black;
- background-color: rgba(255, 255, 255, 0.9);
- left: 1.3rem;
- top: -1rem;
+ background-color: white;
+ overflow: hidden;
}
</style>