Skip to content

Commit

Permalink
feat: show superposed POIs #226
Browse files Browse the repository at this point in the history
  • Loading branch information
wazolab committed Jul 31, 2024
1 parent d235485 commit b94ca59
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 116 deletions.
8 changes: 1 addition & 7 deletions components/MainMap/MapFeatures.vue
Original file line number Diff line number Diff line change
Expand Up @@ -117,28 +117,24 @@ export default defineNuxtComponent({
const { config } = storeToRefs(useSiteStore())
const mapStore = useMapStore()
const { center, selectedFeature } = storeToRefs(mapStore)
const mapStyleLoaded = ref(false)
return {
center,
config,
device,
mapBase: ref<InstanceType<typeof MapBase>>(),
mapStore,
mapStyleLoaded,
selectedFeature,
}
},
data(): {
map: Map
markers: { [id: string]: Marker }
selectedFeatureMarker?: Marker
selectedBackground: MapStyleEnum
} {
return {
map: null!,
markers: {},
selectedBackground: DEFAULT_MAP_STYLE,
}
},
Expand Down Expand Up @@ -259,11 +255,9 @@ export default defineNuxtComponent({
})
this.showSelectedFeature()
this.mapStyleLoaded = true
},
// Map interactions
onClick(e: MapMouseEvent) {
let selectedFeatures = STYLE_LAYERS.map((layerId) => {
return this.map.queryRenderedFeatures(e.point, {
Expand Down Expand Up @@ -315,7 +309,7 @@ export default defineNuxtComponent({
// Map view
onMapRender() {
if (this.mapStyleLoaded && this.selectedFeature) {
if (this.map && this.map.getSource(POI_SOURCE) && this.map.isSourceLoaded(POI_SOURCE) && this.selectedFeature) {
const marker = createMarker((this.selectedFeature.geometry as GeoJSON.Point).coordinates as [number, number])
this.setSelectedFeatureMarker(marker)
}
Expand Down
18 changes: 6 additions & 12 deletions components/Map/MapBase.vue
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,12 @@ export default defineNuxtComponent({
map: maplibregl.Map
poiFilter: PoiFilter | null
poiLayerTemplate: maplibregl.LayerSpecification | undefined
markers: { [id: string]: maplibregl.Marker }
fullAttribution: string
} {
return {
map: null!,
poiFilter: null,
poiLayerTemplate: undefined,
markers: {},
fullAttribution: '',
}
},
Expand Down Expand Up @@ -198,6 +196,7 @@ export default defineNuxtComponent({
.filter(feature => !!feature)
.map((feature, index) => {
feature.id = index
return feature
})
},
Expand Down Expand Up @@ -241,7 +240,7 @@ export default defineNuxtComponent({
cluster: cluster === undefined ? true : cluster,
clusterRadius: 32,
clusterProperties: clusterProps,
clusterMaxZoom: 15,
clusterMaxZoom: 20,
tolerance: 0.6,
data: {
type: 'FeatureCollection',
Expand Down Expand Up @@ -342,7 +341,7 @@ export default defineNuxtComponent({
this.$emit('mapStyleLoad', style)
},
onMapRender(
async onMapRender(
eventName:
| 'mapData'
| 'mapDragEnd'
Expand All @@ -353,14 +352,9 @@ export default defineNuxtComponent({
| 'mapZoomEnd',
event: any,
) {
if (
this.map
&& this.map.getSource(POI_SOURCE)
&& this.map.isSourceLoaded(POI_SOURCE)
) {
this.markers = updateMarkers(
if (this.map && this.map.getSource(POI_SOURCE) && this.map.isSourceLoaded(POI_SOURCE)) {
await updateMarkers(
this.map as maplibregl.Map,
this.markers,
POI_SOURCE,
this.fitBounds,
(feature: ApiPoi, marker?: Marker) => this.$emit('featureClick', feature, marker),
Expand Down Expand Up @@ -415,7 +409,7 @@ export default defineNuxtComponent({
</div>
</template>

<style scoped>
<style lang="scss" scoped>
:deep(.cluster-item) {
cursor: pointer;
}
Expand Down
50 changes: 50 additions & 0 deletions lib/clusters.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import { createApp } from 'vue'
import type { Marker } from 'maplibre-gl'
import type { ApiPoi } from './apiPois'
import TeritorioIconBadge from '~/components/UI/TeritorioIconBadge.vue'

function getMarkerDonutSegment(start: number, end: number, r: number, r0: number, colorFill: string): string {
if (end - start === 1)
end -= 0.00001
Expand Down Expand Up @@ -39,6 +44,51 @@ function getMarkerDonutSegment(start: number, end: number, r: number, r0: number
].join(' ')
}

export function createDeclusterizedCluster(
features: GeoJSON.Feature[],
clusterCoords: [number, number],
markerClickCallBack: ((feature: ApiPoi, marker?: Marker) => void) | undefined,
): HTMLElement {
const clusterWrapper = document.createElement('div')
features.forEach((feature, index) => {
const el = document.createElement('div')
el.id = `m${feature.id}`

createApp(TeritorioIconBadge, {
colorFill: feature.properties?.display.color_fill,
picto: feature.properties?.display.icon,
image: feature.properties!['image:thumbnail'],
size: null,
text: feature.properties?.display.name,
}).mount(el)

if (feature.properties?.editorial?.popup_fields) {
// POI event listener
el.addEventListener('click', (e: MouseEvent) => {
e.stopPropagation()

const middle = features.length / 2
const offset
= index + 1 <= middle
? ((index + 1 - middle) * 32) - 16
: ((index - middle) * 32) + 16

const marker = createMarker(clusterCoords).setOffset([offset, -10])

if (markerClickCallBack)
markerClickCallBack(feature as ApiPoi, marker)
})
}

clusterWrapper.append(el)
})
clusterWrapper.classList.add('cluster-item')
clusterWrapper.style.display = 'flex'
clusterWrapper.style.flexWrap = 'wrap'
clusterWrapper.style.maxWidth = '200px'
return clusterWrapper
}

export function createMarkerDonutChart(countPerColor: Record<string, number>, totalCount: number): HTMLElement {
const r
= totalCount >= 1000
Expand Down
Loading

0 comments on commit b94ca59

Please sign in to comment.