-
Notifications
You must be signed in to change notification settings - Fork 5
/
features.go
101 lines (84 loc) · 2.34 KB
/
features.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
package geonames
import (
"errors"
"fmt"
"strconv"
"strings"
"time"
"github.com/remizovm/geonames/models"
)
// Features returns all features for the specified country iso2 code
func (c *Client) Features(iso2code string) ([]*models.Feature, error) {
var err error
var result []*models.Feature
if len(iso2code) != 2 {
return nil, errors.New("Invalid iso2code")
}
uri := fmt.Sprintf("%s%s.zip", geonamesURL, strings.ToUpper(iso2code))
zipped, err := c.httpGet(uri)
if err != nil {
return nil, err
}
f, err := unzip(zipped)
if err != nil {
return nil, err
}
data, err := getZipData(f, strings.ToUpper(iso2code)+".txt")
if err != nil {
return nil, err
}
parse(data, 0, func(raw [][]byte) bool {
if len(raw) != 19 {
return true
}
geonameID, _ := strconv.Atoi(string(raw[0]))
alternateNames := strings.Split(string(raw[3]), ",")
for i := range alternateNames {
alternateNames[i] = strings.TrimSpace(alternateNames[i])
if alternateNames[i] == "" {
alternateNames = append(alternateNames[:i], alternateNames[i+1:]...)
}
}
latitude, _ := strconv.ParseFloat(string(raw[4]), 64)
longitude, _ := strconv.ParseFloat(string(raw[5]), 64)
var population *int
if string(raw[14]) != "" {
populationInt, err := strconv.Atoi(string(raw[14]))
if err == nil {
population = &populationInt
}
}
var elevation *int
if string(raw[15]) != "" {
elevationInt, err := strconv.Atoi(string(raw[15]))
if err == nil {
elevation = &elevationInt
}
}
dem, _ := strconv.Atoi(string(raw[16]))
modificationDate, _ := time.Parse("2006-02-01", string(raw[18]))
result = append(result, &models.Feature{
GeonameID: geonameID,
Name: string(raw[1]),
ASCIIName: string(raw[2]),
AlternateNames: alternateNames,
Latitude: latitude,
Longitude: longitude,
Class: string(raw[6]),
Code: string(raw[7]),
CountryCode: string(raw[8]),
Cc2: string(raw[9]),
Admin1Code: string(raw[10]),
Admin2Code: string(raw[11]),
Admin3Code: string(raw[12]),
Admin4Code: string(raw[13]),
Population: population,
Elevation: elevation,
Dem: dem,
TimeZone: string(raw[17]),
ModificationDate: modificationDate,
})
return true
})
return result, nil
}