Initial check-in.
This commit is contained in:
commit
f41b1a01e3
5 changed files with 324 additions and 0 deletions
164
pkg/openname/parse.go
Normal file
164
pkg/openname/parse.go
Normal file
|
@ -0,0 +1,164 @@
|
|||
package openname
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/csv"
|
||||
"errors"
|
||||
"io"
|
||||
"strconv"
|
||||
|
||||
"github.com/dhconnelly/rtreego"
|
||||
)
|
||||
|
||||
type Record struct {
|
||||
ID string
|
||||
NamesUri string
|
||||
Name string
|
||||
NameLang string
|
||||
AltName string
|
||||
AltNameLang string
|
||||
Type string
|
||||
LocalType string
|
||||
GeomX float64
|
||||
GeomY float64
|
||||
MostDetailViewRes float64
|
||||
LeastDetailViewRes float64
|
||||
MbrXMin float64
|
||||
MbrYMin float64
|
||||
MbrXMax float64
|
||||
MbrYMax float64
|
||||
PostcodeDistrict string
|
||||
PostcodeDistrictUri string
|
||||
PopulatedPlace string
|
||||
PopulatedPlaceUri string
|
||||
PopulatedPlaceType string
|
||||
DistrictBorough string
|
||||
DistrictBoroughUri string
|
||||
DistrictBoroughType string
|
||||
CountyUnitary string
|
||||
ConutyUnitaryUri string
|
||||
CountyUnitaryType string
|
||||
Region string
|
||||
RegionUri string
|
||||
Country string
|
||||
CountryUri string
|
||||
RelativeSpatialObject string
|
||||
SameAsDbpedia string
|
||||
SameAsGeonames string
|
||||
}
|
||||
|
||||
func (r *Record) Bounds() *rtreego.Rect {
|
||||
p := rtreego.Point{r.MbrXMin, r.MbrYMin}
|
||||
rect, err := rtreego.NewRect(p, []float64{r.MbrXMax - r.MbrXMin, r.MbrYMax - r.MbrYMin})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return rect
|
||||
}
|
||||
|
||||
type Scanner struct {
|
||||
csvReader *csv.Reader
|
||||
nextRecord *Record
|
||||
err error
|
||||
}
|
||||
|
||||
func NewScanner(r io.Reader) (*Scanner, error) {
|
||||
br := bufio.NewReader(r)
|
||||
err := skipBOM(br)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Scanner{csvReader: csv.NewReader(br)}, nil
|
||||
}
|
||||
|
||||
var BOM = [3]byte{0xef, 0xbb, 0xbf}
|
||||
|
||||
func skipBOM(br *bufio.Reader) error {
|
||||
xs, err := br.Peek(3)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if xs[0] == BOM[0] && xs[1] == BOM[1] && xs[2] == BOM[2] {
|
||||
br.Discard(3)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Scanner) Scan() bool {
|
||||
rawRecord, err := s.csvReader.Read()
|
||||
if err != nil {
|
||||
if errors.Is(err, io.EOF) {
|
||||
return false
|
||||
}
|
||||
s.err = err
|
||||
return false
|
||||
}
|
||||
s.nextRecord, err = parseRecord(rawRecord)
|
||||
if err != nil {
|
||||
s.err = err
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *Scanner) Err() error {
|
||||
return s.err
|
||||
}
|
||||
|
||||
func (s *Scanner) Record() *Record {
|
||||
return s.nextRecord
|
||||
}
|
||||
|
||||
func parseRecord(xs []string) (*Record, error) {
|
||||
if len(xs) != 34 {
|
||||
return nil, csv.ErrFieldCount
|
||||
}
|
||||
record := Record{
|
||||
ID: xs[0],
|
||||
NamesUri: xs[1],
|
||||
Name: xs[2],
|
||||
NameLang: xs[3],
|
||||
AltName: xs[4],
|
||||
AltNameLang: xs[5],
|
||||
Type: xs[6],
|
||||
LocalType: xs[7],
|
||||
GeomX: 0,
|
||||
GeomY: 0,
|
||||
MostDetailViewRes: 0,
|
||||
LeastDetailViewRes: 0,
|
||||
MbrXMin: 0,
|
||||
MbrYMin: 0,
|
||||
MbrXMax: 0,
|
||||
MbrYMax: 0,
|
||||
PostcodeDistrict: xs[16],
|
||||
PostcodeDistrictUri: xs[17],
|
||||
PopulatedPlace: xs[18],
|
||||
PopulatedPlaceUri: xs[19],
|
||||
PopulatedPlaceType: xs[20],
|
||||
DistrictBorough: xs[21],
|
||||
DistrictBoroughUri: xs[22],
|
||||
DistrictBoroughType: xs[23],
|
||||
CountyUnitary: xs[24],
|
||||
ConutyUnitaryUri: xs[25],
|
||||
CountyUnitaryType: xs[26],
|
||||
Region: xs[27],
|
||||
RegionUri: xs[28],
|
||||
Country: xs[29],
|
||||
CountryUri: xs[30],
|
||||
RelativeSpatialObject: xs[31],
|
||||
SameAsDbpedia: xs[32],
|
||||
SameAsGeonames: xs[33],
|
||||
}
|
||||
|
||||
for i, p := range []*float64{&record.GeomX, &record.GeomY, &record.MostDetailViewRes, &record.LeastDetailViewRes, &record.MbrXMin, &record.MbrYMin, &record.MbrXMax, &record.MbrYMax} {
|
||||
s := xs[i+8]
|
||||
if s != "" {
|
||||
var err error
|
||||
*p, err = strconv.ParseFloat(s, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
return &record, nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue