Skip to content

Commit a2bac8d

Browse files
committed
init
0 parents  commit a2bac8d

File tree

11 files changed

+2560
-0
lines changed

11 files changed

+2560
-0
lines changed

Diff for: LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2023 Re:Earth contributors
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Diff for: README.md

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# jpareacode
2+
3+
[![Go Reference](https://pkg.go.dev/badge/github.com/eukarya-inc/jpareacode.svg)](https://pkg.go.dev/github.com/eukarya-inc/jpareacode)
4+
5+
日本の都道府県名や市区町村名から、都道府県コードや市区町村コードを取得するライブラリ
6+
7+
```go
8+
package main
9+
10+
import (
11+
jpareacode "github.com/eukarya-inc/jpareacode"
12+
)
13+
14+
func main() {
15+
jpareacode.PrefectureCodeInt("北海道") // 1
16+
jpareacode.PrefectureCodeStrings("北海道") // "01"
17+
jpareacode.PrefectureCodeInts("北海道", "東京都") // [1, 13]
18+
jpareacode.PrefectureCodeStrings("北海道", "東京都") // ["01", "13"]
19+
jpareacode.PrefectureName(1) // "北海道"
20+
jpareacode.PrefectureNames(1, 13) // ["北海道", "東京都"]
21+
jpareacode.Prefectures // []stirng{"北海道", ...}
22+
23+
jpareacode.CityByName(13, "千代田区") // &City{PrefCode:13, Name:"千代田区", Code:13101}
24+
jpareacode.CityByNames("北区") // []City{{PrefCode:1, Name:"北区", Code:1102}, {PrefCode:11, Name:"北区", Code:11102}, ...}
25+
jpareacode.CityByCode(13101) // &City{PrefCode:13, Name:"千代田区", Code:13101}
26+
jpareacode.Cities // []City{{PrefCode:13, Name:"千代田区", Code:13101}, ...}
27+
}
28+
```
29+
30+
データは国土交通省が公開する「都道府県内市区町村一覧取得API」を基にしています。詳しくは以下をご覧ください。
31+
32+
[https://www.land.mlit.go.jp/webland/api.html](https://www.land.mlit.go.jp/webland/api.html)
33+
34+
最終データ更新日:2023/02/20
35+
36+
[MIT License](LICENSE)

Diff for: city.go

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
//go:generate go run ./jpareacodegen --output data.csv
2+
package jpareacode
3+
4+
import (
5+
"bytes"
6+
_ "embed"
7+
"encoding/csv"
8+
"fmt"
9+
"strconv"
10+
)
11+
12+
//go:embed data.csv
13+
var data []byte
14+
15+
var Cities []City
16+
var citym = map[string]City{}
17+
var citymr = map[int]City{}
18+
19+
type City struct {
20+
PrefCode int `json:"prefCode"`
21+
Name string `json:"name"`
22+
Code int `json:"code"`
23+
}
24+
25+
func init() {
26+
r := csv.NewReader(bytes.NewBuffer(data))
27+
data, err := r.ReadAll()
28+
if err != nil {
29+
panic(err)
30+
}
31+
for _, record := range data {
32+
if len(record) < 3 {
33+
panic("invalid length")
34+
}
35+
pcode, err := strconv.Atoi(record[0])
36+
if err != nil {
37+
panic("invalid code")
38+
}
39+
code, err := strconv.Atoi(record[2])
40+
if err != nil {
41+
panic("invalid code")
42+
}
43+
city := City{
44+
PrefCode: pcode,
45+
Code: code,
46+
Name: record[1],
47+
}
48+
Cities = append(Cities, city)
49+
citym[record[0]+record[1]] = city
50+
citymr[code] = city
51+
}
52+
}
53+
54+
// CityByName は、都道府県コードと市区町村名を基に市区町村情報を返します。
55+
func CityByName(prefCode int, name string) *City {
56+
k := FormatPrefectureCode(prefCode) + name
57+
c, ok := citym[k]
58+
if !ok {
59+
return nil
60+
}
61+
return &c
62+
}
63+
64+
// CitiesByName は、市区町村名に合致する全ての市区町村情報を返します。
65+
func CitiesByName(name string) (res []City) {
66+
for _, c := range Cities {
67+
if c.Name == name {
68+
res = append(res, c)
69+
}
70+
}
71+
return
72+
}
73+
74+
// CityByCode は、市区町村コードを基に市区町村情報を返します。
75+
func CityByCode(code int) *City {
76+
c, ok := citymr[code]
77+
if !ok {
78+
return nil
79+
}
80+
return &c
81+
}
82+
83+
// FormatCityCode は、intの市区町村名コードをstringに変換します。無効なコードの場合は空文字列が返されます。
84+
func FormatCityCode(code int) string {
85+
if !ValidateCityCode(code) {
86+
return ""
87+
}
88+
return fmt.Sprintf("%05d", code)
89+
}
90+
91+
// ParseCityCode は、stringの市区町村名コードをintに変換します。パースに失敗した場合や無効なコードの場合は0が返されます。
92+
func ParseCityCode(code string) int {
93+
c, _ := strconv.Atoi(code)
94+
if !ValidateCityCode(c) {
95+
return 0
96+
}
97+
return c
98+
}
99+
100+
// ValidateCityCode は、市区町村コードが有効かどうかを返します。
101+
func ValidateCityCode(code int) bool {
102+
return code >= PrefectureMinCode*100 && code <= (PrefectureMaxCode+1)*1000-1
103+
}

Diff for: city_test.go

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package jpareacode
2+
3+
import (
4+
"reflect"
5+
"testing"
6+
)
7+
8+
func TestCityByName(t *testing.T) {
9+
e := &City{PrefCode: 13, Name: "千代田区", Code: 13101}
10+
if c := CityByName(13, "千代田区"); !reflect.DeepEqual(c, e) {
11+
t.Errorf("expected: %#v, actual: %#v", e, c)
12+
}
13+
e = nil
14+
if c := CityByName(12, "千代田区"); !reflect.DeepEqual(c, e) {
15+
t.Errorf("expected: %#v, actual: %#v", e, c)
16+
}
17+
}
18+
19+
func TestCitiesByName(t *testing.T) {
20+
e := []City{{PrefCode: 13, Name: "千代田区", Code: 13101}}
21+
if c := CitiesByName("千代田区"); !reflect.DeepEqual(c, e) {
22+
t.Errorf("expected: %#v, actual: %#v", e, c)
23+
}
24+
e = nil
25+
if c := CitiesByName("千代田"); !reflect.DeepEqual(c, e) {
26+
t.Errorf("expected: %#v, actual: %#v", e, c)
27+
}
28+
}
29+
30+
func TestCityByCode(t *testing.T) {
31+
e := &City{PrefCode: 13, Name: "千代田区", Code: 13101}
32+
if c := CityByCode(13101); !reflect.DeepEqual(c, e) {
33+
t.Errorf("expected: %#v, actual: %#v", e, c)
34+
}
35+
e = nil
36+
if c := CityByCode(1310); !reflect.DeepEqual(c, e) {
37+
t.Errorf("expected: %#v, actual: %#v", e, c)
38+
}
39+
}
40+
41+
func TestFormatCityCode(t *testing.T) {
42+
if c := FormatCityCode(13101); c != "13101" {
43+
t.Errorf("expected: %s, actual: %s", "13101", c)
44+
}
45+
if c := FormatCityCode(0); c != "" {
46+
t.Errorf("expected: %s, actual: %s", "", c)
47+
}
48+
}
49+
50+
func TestParseCityCode(t *testing.T) {
51+
if c := ParseCityCode("13101"); c != 13101 {
52+
t.Errorf("expected: %d, actual: %d", 13101, c)
53+
}
54+
if c := ParseCityCode(""); c != 0 {
55+
t.Errorf("expected: %d, actual: %d", 0, c)
56+
}
57+
}
58+
59+
func TestValidateCityCode(t *testing.T) {
60+
if !ValidateCityCode(13101) {
61+
t.Error("expected: true, actual: false")
62+
}
63+
if ValidateCityCode(0) {
64+
t.Error("expected: false, actual: true")
65+
}
66+
if ValidateCityCode(50000) {
67+
t.Error("expected: false, actual: true")
68+
}
69+
}

0 commit comments

Comments
 (0)