// Generates all the files that make up the zip-code index. This is // a heirarchical directory/file structure that allows auto-suggest // to work with just static files. func WriteZipIndex(dir string, grid *Grid, n int) error { var zips []*zipIndexEntry // build a list of zips for i := 0; i < grid.W; i++ { for j := 0; j < grid.H; j++ { r := grid.Grid[i][j] if r == nil { continue } for _, zip := range r.Zips { zips = append(zips, &zipIndexEntry{ Zip: zip, I: r.I, J: r.J, }) } } } // sort by descending population util.Sort(len(zips), func(i, j int) bool { return zips[j].Pop < zips[i].Pop }, func(i, j int) { zips[i], zips[j] = zips[j], zips[i] }) return writeZipFiles(dir, "", n, zips) }
// Sort a list of station locations by their distance to a particular point. func SortStationLocs(locs []*StationLoc, x, y float64) { dist := make([]float64, len(locs)) for i, loc := range locs { dist[i] = Distance(loc.X, loc.Y, x, y) } util.Sort(len(locs), func(i, j int) bool { return dist[i] < dist[j] }, func(i, j int) { locs[i], locs[j] = locs[j], locs[i] dist[i], dist[j] = dist[j], dist[i] }) }
// Most of the work will be done here as this computes that data for and writes the // stats files for each region. func WriteStatsFiles(dir string, store *gsod.Store, grid *Grid, tp *TempPref) error { m := map[string][][12]Pct{} for _, station := range store.Stations { m[station.Id()] = make([][12]Pct, len(store.Years)) } for i, year := range store.Years { fmt.Printf("%d\n", year) if err := store.ForEachSummaryInYear(year, func(s *gsod.Summary) error { month := s.Day.Month() - 1 p := &m[s.Station.Id()][i][month] if IsPleasant(s, tp) { p.A++ } p.B++ return nil }); err != nil { return err } } rm := NewRegionStatsMap() var overall []*RegionStats for i := 0; i < grid.W; i++ { for j := 0; j < grid.H; j++ { r := grid.Grid[i][j] if r == nil { continue } var allYears [12]Pct for y := 0; y < len(store.Years); y++ { var thisYear [12]Pct for _, station := range r.Nearest { s := m[station.Id()] for m := 0; m < 12; m++ { thisYear[m].A += s[y][m].A thisYear[m].B += s[y][m].B allYears[m].A += s[y][m].A allYears[m].B += s[y][m].B } } } rs := toRegionStats(r, allYears) rm.Put(rs) overall = append(overall, rs) } } hackKeyLargo(rm) util.Sort(len(overall), func(i, j int) bool { return overall[i].Total > overall[j].Total }, func(i, j int) { overall[i], overall[j] = overall[j], overall[i] }) var s struct { W int H int Regions []*RegionStats } s.W = grid.W s.H = grid.H s.Regions = overall return WriteJson(filepath.Join(dir, fmt.Sprintf("%s.json", tp.Name)), &s) }
// Produce a text label for the region (i,j). First try to find a major // city in the region. If there is not one, we're going to try to produce // a relative name (i.e. EAST OF RENO). func LabelFor(g *Grid, i, j int) string { name, _ := MajorCityOf(g, i, j) if name != "" { return name } var names []string var pops []int lookWest, lookEast, lookNorth, lookSouth := i > 0, i < (g.W-1), j > 0, j < (g.H-1) // east? if lookWest { if name, pop := MajorCityOf(g, i-1, j); name != "" { names = append(names, fmt.Sprintf("EAST OF %s", name)) pops = append(pops, pop) } if lookNorth { if name, pop := MajorCityOf(g, i-1, j-1); name != "" { names = append(names, fmt.Sprintf("SE OF %s", name)) pops = append(pops, pop) } } if lookSouth { if name, pop := MajorCityOf(g, i-1, j+1); name != "" { names = append(names, fmt.Sprintf("NE OF %s", name)) pops = append(pops, pop) } } } // west? if lookEast { if name, pop := MajorCityOf(g, i+1, j); name != "" { names = append(names, fmt.Sprintf("WEST OF %s", name)) pops = append(pops, pop) } if lookNorth { if name, pop := MajorCityOf(g, i+1, j-1); name != "" { names = append(names, fmt.Sprintf("SW OF %s", name)) pops = append(pops, pop) } } if lookSouth { if name, pop := MajorCityOf(g, i+1, j+1); name != "" { names = append(names, fmt.Sprintf("NW OF %s", name)) pops = append(pops, pop) } } } // south? if lookNorth { if name, pop := MajorCityOf(g, i, j-1); name != "" { names = append(names, fmt.Sprintf("SOUTH OF %s", name)) pops = append(pops, pop) } } // north? if lookSouth { if name, pop := MajorCityOf(g, i, j+1); name != "" { names = append(names, fmt.Sprintf("NORTH OF %s", name)) pops = append(pops, pop) } } if len(names) == 0 { return "" } util.Sort(len(names), func(i, j int) bool { return pops[j] < pops[i] }, func(i, j int) { names[i], names[j] = names[j], names[i] pops[i], pops[j] = pops[j], pops[i] }) return names[0] }