impl and test zip.Get, MilesTo, GetStatesWithin, FromCityState
parent
128c98dfbd
commit
db289cb5c8
47
zip/zip.go
47
zip/zip.go
|
|
@ -2,7 +2,6 @@ package zip
|
|||
|
||||
import (
|
||||
_ "embed"
|
||||
"local/truckstop/logtr"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
|
@ -21,11 +20,13 @@ type Zip struct {
|
|||
var zips map[string]Zip
|
||||
|
||||
func init() {
|
||||
if len(zips) > 0 {
|
||||
return
|
||||
}
|
||||
zips = map[string]Zip{}
|
||||
trim := func(s string) string {
|
||||
return strings.Trim(s, `"`)
|
||||
}
|
||||
logtr.Infof("%d", len(csv))
|
||||
for _, line := range strings.Split(csv, "\n")[1:] {
|
||||
strs := strings.Split(line, ",")
|
||||
if len(strs) < 5 {
|
||||
|
|
@ -34,17 +35,26 @@ func init() {
|
|||
zip := trim(strs[0])
|
||||
lat, _ := strconv.ParseFloat(trim(strs[1]), 32)
|
||||
lng, _ := strconv.ParseFloat(trim(strs[2]), 32)
|
||||
city := trim(strs[3])
|
||||
state := trim(strs[4])
|
||||
city := trim(alphafy(strs[3]))
|
||||
state := strings.ToUpper(trim(strs[4]))
|
||||
zips[zip] = Zip{
|
||||
Lat: lat,
|
||||
Lng: lng,
|
||||
City: city,
|
||||
State: state,
|
||||
}
|
||||
logtr.Infof("%+v", zips[zip])
|
||||
}
|
||||
logtr.Infof("%+v to %+v = %v", Get("27006"), Get("84059"), Get("27006").MilesTo(Get("84059")))
|
||||
}
|
||||
|
||||
func alphafy(s string) string {
|
||||
bs := make([]byte, 0, len(s)+1)
|
||||
for i := range s {
|
||||
if (s[i] < 'a' || s[i] > 'z') && (s[i] < 'A' || s[i] > 'Z') {
|
||||
} else {
|
||||
bs = append(bs, s[i])
|
||||
}
|
||||
}
|
||||
return strings.ToLower(string(bs))
|
||||
}
|
||||
|
||||
func (zip Zip) MilesTo(other Zip) int {
|
||||
|
|
@ -73,3 +83,28 @@ func Get(zip string) Zip {
|
|||
}
|
||||
return Zip{}
|
||||
}
|
||||
|
||||
func GetStatesWithin(zip Zip, miles int) []string {
|
||||
states := map[string]struct{}{}
|
||||
for _, other := range zips {
|
||||
if zip.MilesTo(other) <= miles {
|
||||
states[other.State] = struct{}{}
|
||||
}
|
||||
}
|
||||
result := []string{}
|
||||
for state := range states {
|
||||
result = append(result, state)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func FromCityState(city, state string) Zip {
|
||||
city = alphafy(city)
|
||||
state = strings.ToUpper(state)
|
||||
for _, z := range zips {
|
||||
if z.City == city && z.State == state {
|
||||
return z
|
||||
}
|
||||
}
|
||||
return Zip{}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,28 @@
|
|||
package zip
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestZip(t *testing.T) {
|
||||
_ = true
|
||||
zip27006 := Get("27006")
|
||||
zip84059 := Get("84059")
|
||||
t.Logf("27006 = %+v", zip27006)
|
||||
t.Logf("84059 = %+v", zip84059)
|
||||
if zip27006.MilesTo(zip84059) < 1800 {
|
||||
t.Error("failed to compute miles from advance to ut")
|
||||
}
|
||||
sorted := func(s []string) []string {
|
||||
sort.Strings(s)
|
||||
return s
|
||||
}
|
||||
if got := GetStatesWithin(Get("27006"), 100); fmt.Sprint(sorted(got)) != fmt.Sprint(sorted([]string{"NC", "SC", "TN", "VA"})) {
|
||||
t.Error(got)
|
||||
}
|
||||
if got := FromCityState("ADVANCE", "nc"); got != zip27006 {
|
||||
t.Error(got)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue