Add map section with geocoded family pins

This commit is contained in:
Ian Gulliver
2026-08-15 23:21:03 -07:00
parent c56310d219
commit fd52c948db
11 changed files with 350 additions and 13 deletions
+50 -5
View File
@@ -6,18 +6,20 @@ import (
"time"
"heliosian/internal/data"
"heliosian/internal/geocode"
)
const refreshInterval = 5 * time.Minute
type Cache struct {
source data.Source
mu sync.RWMutex
model *Model
source data.Source
geocoder *geocode.Client
mu sync.RWMutex
model *Model
}
func NewCache(source data.Source) (*Cache, error) {
c := &Cache{source: source}
func NewCache(source data.Source, geocoder *geocode.Client) (*Cache, error) {
c := &Cache{source: source, geocoder: geocoder}
if err := c.refresh(); err != nil {
return nil, err
}
@@ -45,6 +47,7 @@ func (c *Cache) refresh() error {
if err != nil {
return err
}
c.geocodeFamilies(model)
c.mu.Lock()
c.model = model
c.mu.Unlock()
@@ -53,3 +56,45 @@ func (c *Cache) refresh() error {
time.Since(start).Round(time.Millisecond))
return nil
}
func (c *Cache) geocodeFamilies(model *Model) {
start := time.Now()
type job struct {
key string
address string
}
jobs := make(chan job)
var wg sync.WaitGroup
var mu sync.Mutex
located := 0
for range 8 {
wg.Add(1)
go func() {
defer wg.Done()
for j := range jobs {
point, err := c.geocoder.Lookup(j.address)
if err != nil {
log.Printf("[ERROR] %v", err)
continue
}
mu.Lock()
family := model.Families[j.key]
family.Lat = point.Lat
family.Lng = point.Lng
model.Families[j.key] = family
located++
mu.Unlock()
}
}()
}
total := 0
for key, family := range model.Families {
if family.Address != "" {
total++
jobs <- job{key: key, address: family.Address}
}
}
close(jobs)
wg.Wait()
log.Printf("geocoded %d of %d family addresses in %s", located, total, time.Since(start).Round(time.Millisecond))
}