@@ -329,47 +329,49 @@ const normalizeSimulationPresets = (presets: SimulationPreset[]): SimulationPres
329329 ) ,
330330 ) ;
331331
332+ const siteNamePosKey = (
333+ site : Pick < Site , "name" | "position" > | Pick < SiteLibraryEntry , "name" | "position" > ,
334+ ) : string =>
335+ `${ site . name . trim ( ) . toLowerCase ( ) } |${ site . position . lat . toFixed ( 6 ) } |${ site . position . lon . toFixed ( 6 ) } ` ;
336+
332337const annotateSitesWithLibraryRefs = ( sites : Site [ ] , library : SiteLibraryEntry [ ] ) : Site [ ] => {
333338 if ( ! sites . length || ! library . length ) return sites ;
334- const libraryByFingerprint = new Map < string , SiteLibraryEntry > ( ) ;
339+ const libraryByFingerprint = new Map < string , SiteLibraryEntry [ ] > ( ) ;
335340 for ( const entry of library ) {
336- const key = [
337- entry . name . trim ( ) . toLowerCase ( ) ,
338- entry . position . lat . toFixed ( 6 ) ,
339- entry . position . lon . toFixed ( 6 ) ,
340- entry . groundElevationM . toFixed ( 1 ) ,
341- entry . antennaHeightM . toFixed ( 1 ) ,
342- ] . join ( "|" ) ;
343- libraryByFingerprint . set ( key , entry ) ;
341+ const key = siteNamePosKey ( entry ) ;
342+ const current = libraryByFingerprint . get ( key ) ?? [ ] ;
343+ libraryByFingerprint . set ( key , [ ...current , entry ] ) ;
344344 }
345345 return sites . map ( ( site ) => {
346346 if ( site . libraryEntryId ) return site ;
347- const key = [
348- site . name . trim ( ) . toLowerCase ( ) ,
349- site . position . lat . toFixed ( 6 ) ,
350- site . position . lon . toFixed ( 6 ) ,
351- site . groundElevationM . toFixed ( 1 ) ,
352- site . antennaHeightM . toFixed ( 1 ) ,
353- ] . join ( "|" ) ;
354- const matched = libraryByFingerprint . get ( key ) ;
355- if ( ! matched ) return site ;
356- return { ...site , libraryEntryId : matched . id } ;
347+ const matches = libraryByFingerprint . get ( siteNamePosKey ( site ) ) ?? [ ] ;
348+ if ( matches . length !== 1 ) return site ;
349+ return { ...site , libraryEntryId : matches [ 0 ] . id } ;
357350 } ) ;
358351} ;
359352
360353const syncLibraryLinkedSiteValues = ( sites : Site [ ] , library : SiteLibraryEntry [ ] ) : Site [ ] => {
361354 if ( ! sites . length || ! library . length ) return sites ;
362355 const byId = new Map < string , SiteLibraryEntry > ( library . map ( ( entry ) => [ entry . id , entry ] ) ) ;
356+ const byNamePos = new Map < string , SiteLibraryEntry [ ] > ( ) ;
357+ for ( const entry of library ) {
358+ const key = siteNamePosKey ( entry ) ;
359+ const current = byNamePos . get ( key ) ?? [ ] ;
360+ byNamePos . set ( key , [ ...current , entry ] ) ;
361+ }
363362 return sites . map ( ( site ) => {
364- if ( ! site . libraryEntryId ) return site ;
365- const entry = byId . get ( site . libraryEntryId ) ;
363+ const direct = site . libraryEntryId ? byId . get ( site . libraryEntryId ) : undefined ;
364+ const inferredMatches = byNamePos . get ( siteNamePosKey ( site ) ) ?? [ ] ;
365+ const inferred = inferredMatches . length === 1 ? inferredMatches [ 0 ] : undefined ;
366+ const entry = direct ?? inferred ;
366367 if ( ! entry ) return site ;
367368 return {
368369 ...site ,
369370 name : entry . name ,
370371 position : entry . position ,
371372 groundElevationM : entry . groundElevationM ,
372373 antennaHeightM : entry . antennaHeightM ,
374+ libraryEntryId : entry . id ,
373375 } ;
374376 } ) ;
375377} ;
0 commit comments