Replies: 2 comments 1 reply
-
I think this could be done if the Marker and DefaultMarker components are updated to expose their internal <script>
import maplibre from 'maplibre-gl';
let markerOptions = [
{ /* coordinates and other stuff here */ },
{ /* coordinates and other stuff here */ },
];
let markers: maplibre.Marker[] = [];
let map: maplibre.Map;
let compasses;
$: if(markers.length && map && !compasses) {
// We've loaded everything so initialize the plugin.
compasses = new MarkerCompass(map, markers);
}
</script>
<MapLibre style="https://styleUrl">
{#each markerOptions as marker, i}
<!-- The `bind:marker` is the part that the library doesn't implement yet -->
<Marker
bind:marker={markers[i]}
lngLat={marker.lngLat}
/>
{/each}
</MapLibre> If you're updating the list of markers after initial creation you would need some additional method to keep the MarkerCompass data in sync with the list of markers. I should be able to make the relevant change to |
Beta Was this translation helpful? Give feedback.
-
Hey @dimfeld, thank you for your swift reply and modifying the library. It doesn't seem to work yet with svelte-maplibre though. I wonder if it's because it might require a value for the container in MarkerCompass. I have a working example with maplibre-gl : <script lang="ts">
import { onMount } from 'svelte';
import { centerCoordinates } from '$lib/stores';
import maplibre from 'maplibre-gl';
import { MarkerCompass } from 'mapboxgl-marker-compass/dist/mapboxgl-marker-compass.mjs';
import locations from '$lib/data/location.json';
import GeoCoder from './GeoCoder.svelte';
let show: boolean = false;
let mapContainer: HTMLDivElement;
let map: maplibre.Map;
let markers: maplibre.Marker[] = [];
let compasses;
onMount(() => {
map = new maplibre.Map({
container: mapContainer,
style: 'https://basemaps.cartocdn.com/gl/positron-gl-style/style.json',
center: $centerCoordinates,
zoom: 14,
});
locations.forEach((loc) => {
const marker = new maplibre.Marker().setLngLat([loc.location[1], loc.location[0]]).addTo(map);
markers.push(marker);
});
if (markers.length && !compasses) {
console.log(markers, map);
compasses = new MarkerCompass(map, markers);
}
});
</script>
<div id="map" bind:this="{mapContainer}" class="map"></div>
<button class="absolute top-2 right-2 w-8 h-8" on:click="{() => (show = !show)}">
<!-- SVG icon here -->
</button>
{#if show}
<GeoCoder />
{/if}
<style>
@import 'mapboxgl-marker-compass/dist/mapboxgl-marker-compass.css';
:global(.map) {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
z-index: -10;
height: 100%;
}
</style> and this is the code with svelte-maplibre, the MarkerCompass plugin shows an empty container value (see console.log). <script lang="ts">
import { centerCoordinates } from '$lib/stores';
import maplibre from 'maplibre-gl';
import { MarkerCompass } from 'mapboxgl-marker-compass/dist/mapboxgl-marker-compass.mjs';
import locations from '$lib/data/location.json';
import GeoCoder from './GeoCoder.svelte';
let show: boolean = false;
import {
MapLibre,
Popup,
Marker,
NavigationControl,
FullscreenControl,
ScaleControl,
GeolocateControl,
} from 'svelte-maplibre';
let mapContain: HTMLDivElement;
console.log(locations);
let markers: maplibre.Marker[] = [];
let map: maplibre.Map | undefined;
let compasses;
$: if (markers.length && map && !compasses) {
compasses = new MarkerCompass(map, markers, {
offset: 10,
width: 20,
height: 50,
backgroundColor: '#3FB1CE',
arrowSize: 4,
arrowOffset: 14,
flyToZoom: 12,
});
console.log('compasses', compasses);
}
</script>
<div id="map" bind:this="{mapContain}">
<MapLibre
mapContainer="{mapContain}"
center="{$centerCoordinates}"
zoom="{14}"
class="map"
style="https://basemaps.cartocdn.com/gl/positron-gl-style/style.json"
bind:map
>
<ScaleControl position="bottom-left" />
<NavigationControl position="bottom-left" />
<GeolocateControl position="bottom-left" fitBoundsOptions="{{ maxZoom: 18 }}" />
<FullscreenControl position="bottom-left" />
{#each locations as loc, i}
<Marker bind:marker="{markers[i]}" lngLat="{[loc.location[1], loc.location[0]]}" draggable class="h-8 w-8">
<!-- SVG icon here -->
<Popup offset="{[0, -10]}">
<div class="text-lg font-bold">{loc.name}</div>
<p>Meat: {loc.meat === false ? 'No' : 'Options'}</p>
{#if loc.image !== undefined}
<img src="{loc.image}" alt="{loc.name}" class="max-h-20" />
{/if}
<a href="https://www.google.com/maps?saddr=My+Location&daddr={loc.location}">Directions</a>
</Popup>
</Marker>
{/each}
</MapLibre>
</div>
<button class="absolute top-2 right-2 w-8 h-8" onclick="{() => (show = !show)}">
<!-- SVG icon here -->
</button>
{#if show}
<GeoCoder />
{/if}
<style>
@import 'mapboxgl-marker-compass/dist/mapboxgl-marker-compass.css';
:global(.map) {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
z-index: -10;
height: 100%;
}
</style> So I'm wondering if it's access to the container? Maybe, I'm missing something else. Thanks for you help! |
Beta Was this translation helpful? Give feedback.
-
Hey, thanks for the wonderful library. I was able to set it up quickly and build some nice maps.
I was wondering if it would be possible to incorporate this mapbox "mapboxgl-marker-compass" plugin. It seems like it needs access to markers but I don't see a way to access them in the library.
https://github.com/marco-land/mapboxgl-marker-compass
As I understand maplibre is a fork of mapbox and this integration could be possible.
Thanks in advance.
Beta Was this translation helpful? Give feedback.
All reactions