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 (
|
import (
|
||||||
_ "embed"
|
_ "embed"
|
||||||
"local/truckstop/logtr"
|
|
||||||
"math"
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -21,11 +20,13 @@ type Zip struct {
|
||||||
var zips map[string]Zip
|
var zips map[string]Zip
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
if len(zips) > 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
zips = map[string]Zip{}
|
zips = map[string]Zip{}
|
||||||
trim := func(s string) string {
|
trim := func(s string) string {
|
||||||
return strings.Trim(s, `"`)
|
return strings.Trim(s, `"`)
|
||||||
}
|
}
|
||||||
logtr.Infof("%d", len(csv))
|
|
||||||
for _, line := range strings.Split(csv, "\n")[1:] {
|
for _, line := range strings.Split(csv, "\n")[1:] {
|
||||||
strs := strings.Split(line, ",")
|
strs := strings.Split(line, ",")
|
||||||
if len(strs) < 5 {
|
if len(strs) < 5 {
|
||||||
|
|
@ -34,17 +35,26 @@ func init() {
|
||||||
zip := trim(strs[0])
|
zip := trim(strs[0])
|
||||||
lat, _ := strconv.ParseFloat(trim(strs[1]), 32)
|
lat, _ := strconv.ParseFloat(trim(strs[1]), 32)
|
||||||
lng, _ := strconv.ParseFloat(trim(strs[2]), 32)
|
lng, _ := strconv.ParseFloat(trim(strs[2]), 32)
|
||||||
city := trim(strs[3])
|
city := trim(alphafy(strs[3]))
|
||||||
state := trim(strs[4])
|
state := strings.ToUpper(trim(strs[4]))
|
||||||
zips[zip] = Zip{
|
zips[zip] = Zip{
|
||||||
Lat: lat,
|
Lat: lat,
|
||||||
Lng: lng,
|
Lng: lng,
|
||||||
City: city,
|
City: city,
|
||||||
State: state,
|
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 {
|
func (zip Zip) MilesTo(other Zip) int {
|
||||||
|
|
@ -73,3 +83,28 @@ func Get(zip string) Zip {
|
||||||
}
|
}
|
||||||
return 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
|
package zip
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
func TestZip(t *testing.T) {
|
func TestZip(t *testing.T) {
|
||||||
_ = true
|
_ = 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