Skip to content

Commit

Permalink
Merge pull request #1410 from geospoc/fix/reactive-marker-and-cleanup…
Browse files Browse the repository at this point in the history
…-geojson-layer

fix: minor housekeeping 🎉

Signed-off-by: Vinayak Kulkarni 19776877+vinayakkulkarni@users.noreply.github.com
  • Loading branch information
vinayakkulkarni committed Mar 14, 2023
2 parents a7d25d2 + 8e71b2d commit 19c3b72
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 49 deletions.
18 changes: 10 additions & 8 deletions src/layers/mapbox/VLayerMapboxGeojson.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@
</div>
</template>
<script lang="ts">
import type { FeatureCollection } from 'geojson';
import type {
LayerSpecification as AnyLayer,
SourceSpecification as AnySource,
} from 'maplibre-gl';
import type { PropType, Ref } from 'vue';
import { defineComponent, onMounted, ref, watch } from 'vue';
import { defineComponent, onMounted, onBeforeUnmount, ref, watch } from 'vue';
import { injectStrict, MapKey } from '../../utils';
export default defineComponent({
Expand All @@ -27,7 +26,7 @@
required: true,
},
source: {
type: Object as PropType<FeatureCollection>,
type: Object as PropType<AnySource>,
required: true,
},
layer: {
Expand All @@ -50,10 +49,6 @@
id: props.layerId,
source: props.sourceId,
};
const source: AnySource = {
type: 'geojson',
data: props.source,
};
map.value.on('style.load', () => {
// https://github.com/mapbox/mapbox-gl-js/issues/2268#issuecomment-401979967
Expand Down Expand Up @@ -81,13 +76,20 @@
addLayer();
});
onBeforeUnmount(() => {
if (map.value.getLayer(props.layerId)) {
map.value.removeLayer(props.layerId);
map.value.removeSource(props.sourceId);
}
});
/**
* Re–adds the layer when style changed
*
* @returns {void}
*/
function addLayer(): void {
map.value.addSource(props.sourceId, source);
map.value.addSource(props.sourceId, props.source);
map.value.addLayer(layer, props.before);
}
},
Expand Down
117 changes: 82 additions & 35 deletions src/markers/VMarker.vue
Original file line number Diff line number Diff line change
@@ -1,40 +1,42 @@
<template>
<section :id="`marker-${Date.now()}`">
<v-popup
:marker="marker"
:options="popupOptions"
:coordinates="coordinates"
>
<slot />
</v-popup>
<section :id="`marker-${Date.now()}`" class="absolute">
<slot :set-ref="setSlotRef" name="markers" />
<template v-if="isMarkerAvailable">
<v-popup
:marker="marker"
:options="popupOptions"
:coordinates="coordinates"
>
<slot />
</v-popup>
</template>
</section>
</template>
<script lang="ts">
import type { LngLatLike, MarkerOptions, PopupOptions } from 'maplibre-gl';
import { Marker } from 'maplibre-gl';
import type { PropType, Ref } from 'vue';
import { defineComponent, onMounted, ref } from 'vue';
import { defineComponent, onMounted, onBeforeUnmount, ref, watch } from 'vue';
import { markerDOMEvents, markerMapEvents } from '../constants/events';
import VPopup from '../popups/VPopup.vue';
import { MapKey } from '../utils/symbols';
import { injectStrict } from '../utils';
import { injectStrict, MapKey } from '../utils';
export default defineComponent({
name: 'VMarker',
components: {
VPopup,
},
props: {
options: {
type: Object as PropType<MarkerOptions>,
default: () => ({} as MarkerOptions),
required: true,
},
coordinates: {
type: [Object, Array] as PropType<LngLatLike>,
default: () => ({}),
required: true,
},
options: {
type: Object as PropType<MarkerOptions>,
default: () => ({} as MarkerOptions),
required: false,
},
popupOptions: {
type: Object as PropType<PopupOptions>,
default: () => ({} as PopupOptions),
Expand All @@ -55,8 +57,50 @@
],
setup(props, { emit }) {
let map = injectStrict(MapKey);
let marker: Marker = new Marker(props.options);
let marker: Ref<Marker> = ref({}) as Ref<Marker>;
let loaded: Ref<boolean> = ref(true);
let isMarkerAvailable = ref(false);
let slotRef: Ref<HTMLElement | null> = ref(null);
const setSlotRef = (el: HTMLElement) => {
slotRef.value = el;
};
watch(marker, (marker) => {
if ('_map' in marker) {
isMarkerAvailable.value = true;
} else {
isMarkerAvailable.value = false;
}
});
onMounted(() => {
if (loaded.value) {
if (slotRef.value !== null) {
// add marker to map
marker.value = new Marker({
element: slotRef.value!,
...props.options,
});
setMarkerCoordinates(marker.value);
addToMap(marker.value);
setCursorPointer(marker.value);
listenMarkerEvents(marker.value);
} else {
marker.value = new Marker(props.options);
setMarkerCoordinates(marker.value);
addToMap(marker.value);
setCursorPointer(marker.value);
listenMarkerEvents(marker.value);
}
} else {
removeFromMap(marker.value);
}
});
onBeforeUnmount(() => {
removeFromMap(marker.value);
});
map.value.on('style.load', () => {
// https://github.com/mapbox/mapbox-gl-js/issues/2268#issuecomment-401979967
Expand All @@ -71,59 +115,55 @@
styleTimeout();
});
onMounted(() => {
if (loaded.value) {
setMarkerCoordinates();
addToMap();
setCursorPointer();
} else {
removeFromMap();
}
listenMarkerEvents();
});
/**
* Set marker coordinates
*
* @param {Marker} marker - Marker
* @returns {void}
*/
function setMarkerCoordinates(): void {
function setMarkerCoordinates(marker: Marker): void {
marker.setLngLat(props.coordinates);
}
/**
* Sets the Cursor to Pointer
*
* @param {Marker} marker - Marker
* @returns {void}
*/
function setCursorPointer(): void {
function setCursorPointer(marker: Marker): void {
marker.getElement().style.cursor = props.cursor || 'default';
}
/**
* Add marker to map
*
* @param {Marker} marker - Marker
* @returns {void}
*/
function addToMap(): void {
function addToMap(marker: Marker): void {
marker.addTo(map.value);
emit('added', { marker });
}
/**
* Remove marker from map
*
* @param {Marker} marker - Marker
* @returns {void}
*/
function removeFromMap(): void {
marker.remove();
emit('removed');
function removeFromMap(marker: Marker): void {
if (isMarkerAvailable.value) {
marker.remove();
emit('removed');
}
}
/**
* Listen to events
*
* @param {Marker} marker - Marker
* @returns {void}
*/
function listenMarkerEvents(): void {
function listenMarkerEvents(marker: Marker): void {
let coordinates: LngLatLike;
// Listen to Marker Mapbox events
markerMapEvents.forEach((event: string) => {
Expand All @@ -148,8 +188,15 @@
}
return {
isMarkerAvailable,
marker,
setSlotRef,
};
},
});
</script>
<style>
.absolute {
position: absolute !important;
}
</style>
17 changes: 11 additions & 6 deletions src/popups/VPopup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@
</template>
<script lang="ts">
import type { LngLatLike, Map, Marker, PopupOptions } from 'maplibre-gl';
import { Popup } from 'maplibre-gl';
import type { PropType, Ref } from 'vue';
import { Popup } from 'maplibre-gl';
import { defineComponent, onBeforeUnmount, onMounted, ref } from 'vue';
import { popupEvents } from '../constants/events';
import { MapKey } from '../utils/symbols';
import { injectStrict } from '../utils';
import { injectStrict, MapKey } from '../utils';
export default defineComponent({
name: 'VPopup',
Expand Down Expand Up @@ -53,6 +52,7 @@
onMounted(() => {
if (loaded.value) {
setPopupContent();
setPopupCoordinates();
addToMarker();
listenPopupEvents();
Expand All @@ -67,15 +67,20 @@
removePopupEvents();
});
/**
* Sets the HTML content for the popup
*
* @returns {void}
*/
function setPopupContent(): void {
popup.setDOMContent(content.value as Node);
}
/**
* Set popup coordinates
*
* @returns {void}
*/
function setPopupCoordinates(): void {
const { outerHTML }: { outerHTML: string } =
content.value!.children[0].children[0];
popup.setHTML(outerHTML);
popup.setLngLat(props.coordinates);
}
Expand Down

0 comments on commit 19c3b72

Please sign in to comment.