-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
111 lines (89 loc) · 2.38 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"os"
"regexp"
"strconv"
"strings"
"github.com/PuerkitoBio/goquery"
)
func main() {
// to get city name
r := regexp.MustCompile("<(?:br/|BR/)>(.*)")
doc, err := goquery.NewDocument("http://www.gsi.go.jp/KOKUJYOHO/CENTER/kendata/kumamoto_heso.htm")
if err != nil {
log.Fatal(err)
}
html, err := doc.Html()
if err != nil {
log.Fatal(err)
}
cityFinds := r.FindAllStringSubmatch(html, -1)
pageTitle := doc.Find("title").Text()
m := make(map[string]map[string]float64)
doc.Find("table").Each(func(ti int, ts *goquery.Selection) {
if ti > len(cityFinds) {
log.Fatalf("ti is bigger than len(finds). ti is %v, len(finds) is %v\n", ti, len(cityFinds))
}
lng := dmsToDeg(ts.Find("TR").Eq(1).Find("TD").Eq(1).Text()[1:])
lat := dmsToDeg(ts.Find("TR").Eq(2).Find("TD").Eq(1).Text()[1:])
city := normalize(cityFinds[ti][1])
// city: "" -> city: "熊本県"
if city == "" {
city = pageTitle
}
m[city] = map[string]float64{
"lng": lng,
"lat": lat,
}
fmt.Printf(`"%s",`, city)
})
dumpJSON("./output/data.json", m)
}
// take out after "郡". e.g) 葦北郡芦北町 => 芦北町
// If there is "市" and "区", "区" is given priority. e.g) 熊本市中央区 => 中央区
func normalize(city string) string {
idx := strings.Index(city, "郡")
if idx != -1 {
city = city[idx+3:]
}
idxShi := strings.Index(city, "市")
idxKu := strings.Index(city, "区")
if idxShi != -1 && idxKu != -1 {
city = city[idxShi+3:]
}
return city
}
// 35°41′28.5576″ => 35.691266
func dmsToDeg(dms string) float64 {
var degree float64
var min float64
var sec float64
degSplit := strings.Split(dms, "°")
if len(degSplit) != 2 {
log.Fatalf("invalid dms(degeee) format: %v\n", dms)
}
degree, _ = strconv.ParseFloat(degSplit[0], 64)
minSplit := strings.Split(degSplit[1], "′")
if len(minSplit) != 2 {
log.Fatalf("invalid dms(minute) format: %v\n", dms)
}
min, _ = strconv.ParseFloat(minSplit[0], 64)
l := len(minSplit[1]) - 3
if minSplit[1][l:] != "″" {
log.Fatalf("invalid dms(second) format: %v\n", dms)
}
// 30″ -> 30
sec, _ = strconv.ParseFloat(minSplit[1][:l], 64)
return degree + (min / 60) + (sec / 60 / 60)
}
func dumpJSON(path string, m map[string]map[string]float64) error {
d, err := json.Marshal(m)
if err != nil {
return err
}
return ioutil.WriteFile(path, d, os.ModePerm)
}