Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 1 addition & 9 deletions examples/generic/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,7 @@ let colorScheme = 'light'

// arbitrary condition for testing
const isEvenId = (mmlid) => Number(mmlid.slice(-1)) % 2 === 0

// NOTE: This function is only usable if the layer is clustered
const isReportSelectable = (feature) =>
feature
.get('features')
.reduce(
(accumulator, current) => isEvenId(current.get('mmlid')) || accumulator,
false
)
const isReportSelectable = (feature) => isEvenId(feature.get('mmlid'))

const map = await createMap(
'polarstern',
Expand Down
9 changes: 1 addition & 8 deletions examples/github-io/components/HeroPolarMap.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
</template>

<script setup lang="ts">
import type { Feature } from 'ol'
import type { MpapiParameters } from '@/lib/getFeatures/types'

import { createMap } from '@polar/polar/client'
Expand All @@ -20,13 +19,7 @@ const reports = '6059'
const hamburgBorder = '1693'

const isEvenId = (mmlid: string) => Number(mmlid.slice(-1)) % 2 === 0

const isReportSelectable = (feature: Feature) =>
(feature.get('features') as Feature[]).reduce(
(acc: boolean, curr: Feature) =>
isEvenId(curr.get('mmlid') as string) || acc,
false
)
const isReportSelectable = (feature) => isEvenId(feature.get('mmlid'))

onMounted(async () => {
await createMap(
Expand Down
10 changes: 1 addition & 9 deletions examples/snowbox/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,7 @@

// arbitrary condition for testing
const isEvenId = (mmlid) => Number(mmlid.slice(-1)) % 2 === 0

// NOTE: This function is only usable if the layer is clustered
const isReportSelectable = (feature) =>
feature
.get('features')
.reduce(
(accumulator, current) => isEvenId(current.get('mmlid')) || accumulator,
false
)
const isReportSelectable = (feature) => isEvenId(feature.get('mmlid'))

const map = await createMap(
'snowbox',
Expand All @@ -96,7 +88,7 @@
colorScheme,
startCenter: [565874, 5934140],
layers: [
// TODO: Add internalization to snowbox

Check warning on line 91 in examples/snowbox/index.js

View workflow job for this annotation

GitHub Actions / Linting

Unexpected 'todo' comment: 'TODO: Add internalization to snowbox'
{
id: basemapId,
visibility: true,
Expand Down
6 changes: 4 additions & 2 deletions src/core/components/PolarContainer.ce.vue
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@
import { useCoreStore } from '../stores'
import { useContextMenuStore } from '../stores/contextMenu'
import { useMainStore } from '../stores/main'
import { useMarkerStore } from '../stores/marker'
import { useMoveHandleStore } from '../stores/moveHandle'
import { CoreId } from '../types'
import { loadKern } from '../utils/loadKern'
import { teardownMarkers } from '../utils/map/setupMarkers'
import { mapZoomOffset } from '../utils/mapZoomOffset'
import ContextMenu from './ContextMenu.ce.vue'
import MoveHandle from './MoveHandle.ce.vue'
Expand Down Expand Up @@ -223,6 +223,8 @@
)
}

const markerStore = useMarkerStore()

onMounted(() => {
mainStore.lightElement = useHost()
mainStore.shadowRoot = useShadowRoot()
Expand All @@ -238,7 +240,7 @@
resizeObserver.observe(polarWrapper.value as Element)
updateClientDimensions()

// FIXME: Improve types for lightElement

Check warning on line 243 in src/core/components/PolarContainer.ce.vue

View workflow job for this annotation

GitHub Actions / Linting

Unexpected 'fixme' comment: 'FIXME: Improve types for lightElement'
// This is necessary for making `getStore` work
;(mainStore.lightElement as { store?: unknown }).store = useCoreStore()

Expand Down Expand Up @@ -266,7 +268,7 @@
mapEl.removeEventListener('contextmenu', openContextMenu)
document.removeEventListener('pointerdown', contextMenuStore.dismiss)
if (mainStore.configuration.markers) {
teardownMarkers(mainStore.map)
markerStore.teardown()
}
mainStore.map.dispose()
mapEl.replaceChildren()
Expand Down
5 changes: 3 additions & 2 deletions src/core/components/PolarMap.ce.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ import { markRaw, onBeforeUnmount, onMounted, useTemplateRef, watch } from 'vue'

import { useContextMenuStore } from '../stores/contextMenu'
import { useMainStore } from '../stores/main'
import { useMarkerStore } from '../stores/marker'
import { CoreId } from '../types'
import { checkServiceAvailability } from '../utils/checkServiceAvailability'
import { createKeyboardInteractions } from '../utils/interactions'
import { setupMarkers } from '../utils/map/setupMarkers'
import { setupStyling } from '../utils/map/setupStyling'
import { updateDragAndZoomInteractions } from '../utils/map/updateDragAndZoomInteractions'

Expand All @@ -35,6 +35,7 @@ const emit = defineEmits(['updateListeners', 'wheel'])
const mainStore = useMainStore()
const { hasWindowSize, hasSmallDisplay, center, extent, zoom } =
storeToRefs(mainStore)
const markerStore = useMarkerStore()
const contextMenuStore = useContextMenuStore()

function onMove() {
Expand Down Expand Up @@ -109,7 +110,7 @@ onMounted(async () => {
checkServiceAvailability(mainStore.configuration, mainStore.serviceRegister)
}
if (mainStore.configuration.markers) {
setupMarkers(mainStore.map)
markerStore.setup()
}
await setupStyling(
mainStore.map,
Expand Down
71 changes: 71 additions & 0 deletions src/core/composables/useClusterMarker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import type { Feature, Map } from 'ol'
import type { Point } from 'ol/geom'
import type { Style } from 'ol/style'
import type { ShallowRef } from 'vue'

import { computed, markRaw, shallowRef, watch } from 'vue'

import { findLayer } from '@/lib/findLayer'
import getCluster from '@/lib/getCluster'

import { useMainStore } from '../stores/main'

function getClusterSafe(map: Map, feature: Feature) {
const layerId = feature.get('_polarLayerId') as string
// @ts-expect-error | Found layers always have a source and getDistance is defined on cluster sources.
return typeof findLayer(map, layerId)?.getSource().getDistance === 'function'
? getCluster(map, feature, '_polarLayerId')
: feature
}

export function useClusterMarker(
feature: ShallowRef<Feature | null>,
style: (active: boolean, feature: Feature) => Style
) {
const mainStore = useMainStore()

const cluster = shallowRef<Feature | null>(null)
const clusterFeatures = computed(
() => (cluster.value?.get('features') ?? []) as Feature[]
)
const clusterCoordinates = computed(() =>
cluster.value === null
? null
: ((cluster.value.getGeometry() as Point).getCoordinates() as [
number,
number,
])
)

function updateCluster(newFeature: Feature | null) {
const newCluster =
newFeature === null
? null
: markRaw(getClusterSafe(mainStore.map, newFeature))

if (cluster.value === newCluster) {
return
}

if (cluster.value) {
cluster.value.setStyle(style(false, cluster.value))
}

cluster.value = newCluster

if (cluster.value) {
cluster.value.setStyle(style(true, cluster.value))
}
}

watch(feature, updateCluster, { immediate: true })

watch(
() => mainStore.zoom,
() => {
updateCluster(feature.value)
}
)

return { cluster, clusterFeatures, clusterCoordinates }
}
64 changes: 57 additions & 7 deletions src/core/stores/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,9 @@
*/
/* eslint-enable tsdoc/syntax */

import type { Feature } from 'ol'

import { acceptHMRUpdate, defineStore, storeToRefs } from 'pinia'
import { computed } from 'vue'
import { computed, readonly } from 'vue'

import { updateSelection } from '../utils/map/setupMarkers'
import { useContextMenuStore } from './contextMenu'
import { useMainStore } from './main'
import { useMarkerStore } from './marker'
Expand Down Expand Up @@ -286,11 +283,41 @@ export const useCoreStore = defineStore('core', () => {
*
* @alpha
*/
hoveredFeature: markerStoreRefs.hovered,
hoveredFeature: markerStoreRefs.hoveredFeature,

/**
* Feature that is hovered by the user with a marker.
* If the layer does not use clustering, this is the same as {@link hoveredFeature}.
* Otherwise, this is the cluster feature that contains the {@link hoveredFeature}.
*
* @readonly
* @alpha
*/
hoveredCluster: readonly(markerStoreRefs.hoveredCluster),

/**
* Features that are hovered by the user with a marker.
* If the layer does not use clustering, this is an array with a single element, which is the same as {@link hoveredFeature}.
* Otherwise, this is an array of all features that are contained in the {@link hoveredCluster}.
*
* @readonly
* @alpha
*/
hoveredClusterFeatures: markerStoreRefs.hoveredClusterFeatures,

/**
* Coordinates that were hovered by the user with a marker.
*
* @readonly
*/
hoveredCoordinates: computed(() => markerStore.hoveredCoordinates),

/**
* Feature that was selected by the user with a marker.
*
* You may not set this to a cluster feature.
* Setting this value to a cluster feature has no effect, however, this may change in the future.
*
* If this value is modified, the newly selected feature is centered on the map.
*
* @remarks
Expand All @@ -301,12 +328,35 @@ export const useCoreStore = defineStore('core', () => {
* @alpha
*/
selectedFeature: computed({
get: () => markerStore.selected,
get: () => markerStore.selectedFeature,
set: (feature) => {
updateSelection(mainStore.map, feature as Feature, true)
if (feature?.get('features')) {
return
}
markerStore.selectedFeature = feature
},
}),

/**
* Feature that is marked as selected on the map.
* If the layer does not use clustering, this is the same as {@link selectedFeature}.
* Otherwise, this is the cluster feature that contains the {@link selectedFeature}.
*
* @readonly
* @alpha
*/
selectedCluster: readonly(markerStoreRefs.selectedCluster),

/**
* Features that are marked as selected on the map.
* If the layer does not use clustering, this is an array with a single element, which is the same as {@link selectedFeature}.
* Otherwise, this is an array of all features that are contained in the {@link selectedCluster}.
*
* @readonly
* @alpha
*/
selectedClusterFeatures: markerStoreRefs.selectedClusterFeatures,

/**
* Coordinates that were selected by the user with a marker.
*
Expand Down
Loading
Loading