forked from TrueCloudLab/frostfs-locode-db
[#7] Add local tool for building database file
Added frostfs-locode-db CLI utility that can generate and view UN/LOCODE database files. Go package git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/locode copied to this repository to eliminate interdependency between frostfs-node and frostfs-locode-db projects. The process of building database files reduced to starting make command. Signed-off-by: George Bartolomey <george@bh4.ru>
This commit is contained in:
parent
7e523f1a28
commit
840b20538b
30 changed files with 2317 additions and 4 deletions
93
pkg/locode/db/point.go
Normal file
93
pkg/locode/db/point.go
Normal file
|
@ -0,0 +1,93 @@
|
|||
package locodedb
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
locodecolumn "git.frostfs.info/TrueCloudLab/frostfs-locode-db/pkg/locode/column"
|
||||
)
|
||||
|
||||
// Point represents a 2D geographic point.
|
||||
type Point struct {
|
||||
lat, lng float64
|
||||
}
|
||||
|
||||
// NewPoint creates, initializes and returns a new Point.
|
||||
func NewPoint(lat, lng float64) *Point {
|
||||
return &Point{
|
||||
lat: lat,
|
||||
lng: lng,
|
||||
}
|
||||
}
|
||||
|
||||
// Latitude returns the Point's latitude.
|
||||
func (p Point) Latitude() float64 {
|
||||
return p.lat
|
||||
}
|
||||
|
||||
// Longitude returns the Point's longitude.
|
||||
func (p Point) Longitude() float64 {
|
||||
return p.lng
|
||||
}
|
||||
|
||||
// PointFromCoordinates converts a UN/LOCODE coordinates to a Point.
|
||||
func PointFromCoordinates(crd *locodecolumn.Coordinates) (*Point, error) {
|
||||
if crd == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
cLat := crd.Latitude()
|
||||
cLatDeg := cLat.Degrees()
|
||||
cLatMnt := cLat.Minutes()
|
||||
|
||||
lat, err := toDecimal(cLatDeg[:], cLatMnt[:])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not parse latitude: %w", err)
|
||||
}
|
||||
|
||||
if !cLat.Hemisphere().North() {
|
||||
lat = -lat
|
||||
}
|
||||
|
||||
cLng := crd.Longitude()
|
||||
cLngDeg := cLng.Degrees()
|
||||
cLngMnt := cLng.Minutes()
|
||||
|
||||
lng, err := toDecimal(cLngDeg[:], cLngMnt[:])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not parse longitude: %w", err)
|
||||
}
|
||||
|
||||
if !cLng.Hemisphere().East() {
|
||||
lng = -lng
|
||||
}
|
||||
|
||||
return &Point{
|
||||
lat: lat,
|
||||
lng: lng,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func toDecimal(intRaw, minutesRaw []byte) (float64, error) {
|
||||
integer, err := strconv.ParseFloat(string(intRaw), 64)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("could not parse integer part: %w", err)
|
||||
}
|
||||
|
||||
decimal, err := minutesToDegrees(minutesRaw)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("could not parse decimal part: %w", err)
|
||||
}
|
||||
|
||||
return integer + decimal, nil
|
||||
}
|
||||
|
||||
// minutesToDegrees converts minutes to decimal part of a degree.
|
||||
func minutesToDegrees(raw []byte) (float64, error) {
|
||||
minutes, err := strconv.ParseFloat(string(raw), 64)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return minutes / 60, nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue