@@ -16,47 +16,59 @@ import {
1616const ACTIVE_Z_INDEX = 1800
1717const INACTIVE_Z_INDEX = 900
1818
19- const RouteAnchor = React . memo ( ( { entry, selected, onSelect, routeCount } ) => {
20- const baseIcon = React . useMemo ( ( ) => routeMarker ( 'start' ) , [ ] )
21- const badgeIcon = React . useMemo ( ( ) => {
22- if ( routeCount <= 1 ) return null
23- return divIcon ( {
24- className : 'route-count-wrapper' ,
25- html : `<span class="route-count-badge">${ routeCount } </span>` ,
26- iconSize : [ 0 , 0 ] ,
27- iconAnchor : [ 0 , 0 ] ,
28- } )
29- } , [ routeCount ] )
19+ const RouteAnchor = React . memo (
20+ ( {
21+ entry,
22+ selected,
23+ onSelect,
24+ routeCount,
25+ variant = 'start' ,
26+ icon = null ,
27+ } ) => {
28+ const baseIcon = React . useMemo (
29+ ( ) => icon || routeMarker ( variant === 'destination' ? 'end' : 'start' ) ,
30+ [ icon , variant ] ,
31+ )
32+ const badgeIcon = React . useMemo ( ( ) => {
33+ if ( routeCount <= 1 ) return null
34+ return divIcon ( {
35+ className : 'route-count-wrapper' ,
36+ html : `<span class="route-count-badge route-count-badge--${ variant } ">${ routeCount } </span>` ,
37+ iconSize : [ 0 , 0 ] ,
38+ iconAnchor : [ 0 , 0 ] ,
39+ } )
40+ } , [ routeCount , variant ] )
3041
31- return (
32- < >
33- { ! selected && (
34- < Marker
35- position = { [ entry . lat , entry . lon ] }
36- icon = { baseIcon }
37- zIndexOffset = { INACTIVE_Z_INDEX }
38- riseOnHover
39- eventHandlers = { {
40- click : ( ) => onSelect ( entry . key ) ,
41- } }
42- title = { routeCount > 1 ? `${ routeCount } routes` : '' }
43- />
44- ) }
45- { badgeIcon && (
46- < Marker
47- position = { [ entry . lat , entry . lon ] }
48- icon = { badgeIcon }
49- interactive = { false }
50- keyboard = { false }
51- pane = "tooltipPane"
52- zIndexOffset = {
53- selected ? ACTIVE_Z_INDEX + 200 : INACTIVE_Z_INDEX + 200
54- }
55- />
56- ) }
57- </ >
58- )
59- } )
42+ return (
43+ < >
44+ { variant !== 'destination' && ! selected && (
45+ < Marker
46+ position = { [ entry . lat , entry . lon ] }
47+ icon = { baseIcon }
48+ zIndexOffset = { INACTIVE_Z_INDEX }
49+ riseOnHover
50+ eventHandlers = { {
51+ click : ( ) => onSelect ( entry . key ) ,
52+ } }
53+ title = { routeCount > 1 ? `${ routeCount } routes` : '' }
54+ />
55+ ) }
56+ { badgeIcon && (
57+ < Marker
58+ position = { [ entry . lat , entry . lon ] }
59+ icon = { badgeIcon }
60+ interactive = { false }
61+ keyboard = { false }
62+ pane = "tooltipPane"
63+ zIndexOffset = {
64+ selected ? ACTIVE_Z_INDEX + 200 : INACTIVE_Z_INDEX + 200
65+ }
66+ />
67+ ) }
68+ </ >
69+ )
70+ } ,
71+ )
6072
6173const ActiveRoute = React . memo ( ( { selection } ) => {
6274 const route = useRouteStore (
@@ -101,18 +113,26 @@ export function RouteLayer({ routes }) {
101113 } ,
102114 } )
103115
104- const destinationCoords = React . useMemo ( ( ) => {
105- if ( ! compactView ) return new Set ( )
116+ const destinationSummary = React . useMemo ( ( ) => {
117+ if ( ! compactView )
118+ return { keys : new Set ( ) , icons : new Map ( ) , counts : new Map ( ) }
106119 const keys = new Set ( )
120+ const icons = new Map ( )
121+ const counts = new Map ( )
107122 activeRoutes . forEach ( ( selection ) => {
108123 const route = routeCache [ selection . routeId ]
109124 if ( ! route ) return
110125 const isForward = selection . orientation === 'forward'
111126 const lat = isForward ? route . end_lat : route . start_lat
112127 const lon = isForward ? route . end_lon : route . start_lon
113- keys . add ( getRouteCoordKey ( lat , lon ) )
128+ const coordKey = getRouteCoordKey ( lat , lon )
129+ keys . add ( coordKey )
130+ counts . set ( coordKey , ( counts . get ( coordKey ) || 0 ) + 1 )
131+ if ( ! icons . has ( coordKey ) ) {
132+ icons . set ( coordKey , routeMarker ( 'end' ) )
133+ }
114134 } )
115- return keys
135+ return { keys, icons , counts }
116136 } , [ activeRoutes , routeCache , compactView ] )
117137
118138 const anchors = React . useMemo ( ( ) => {
@@ -158,7 +178,25 @@ export function RouteLayer({ routes }) {
158178 < >
159179 { anchors . map ( ( { entry, routeCount } ) => {
160180 const entryCoordKey = getRouteCoordKey ( entry . lat , entry . lon )
161- if ( destinationCoords . has ( entryCoordKey ) && entry . key !== activePoiId ) {
181+ const iconOverride = destinationSummary . icons . get ( entryCoordKey )
182+ const destinationCount = destinationSummary . counts . get ( entryCoordKey )
183+ if ( destinationCount && destinationCount > 1 ) {
184+ return (
185+ < RouteAnchor
186+ key = { `${ entry . key } -destination` }
187+ entry = { entry }
188+ selected = { entry . key === activePoiId }
189+ onSelect = { selectPoi }
190+ routeCount = { destinationCount }
191+ variant = "destination"
192+ icon = { iconOverride || undefined }
193+ />
194+ )
195+ }
196+ if (
197+ destinationSummary . keys . has ( entryCoordKey ) &&
198+ entry . key !== activePoiId
199+ ) {
162200 return null
163201 }
164202 return (
@@ -167,7 +205,9 @@ export function RouteLayer({ routes }) {
167205 entry = { entry }
168206 selected = { entry . key === activePoiId }
169207 onSelect = { selectPoi }
170- routeCount = { routeCount }
208+ routeCount = { destinationCount || routeCount }
209+ variant = "start"
210+ icon = { iconOverride || undefined }
171211 />
172212 )
173213 } ) }
0 commit comments