This commit is contained in:
parent
0e680ad189
commit
e926800f44
30
.drone.yml
Normal file
30
.drone.yml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
kind: pipeline
|
||||||
|
type: kubernetes
|
||||||
|
name: default
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: test
|
||||||
|
image: golang:1.18
|
||||||
|
volumes:
|
||||||
|
- name: deps
|
||||||
|
path: /go
|
||||||
|
commands:
|
||||||
|
- go test -v
|
||||||
|
- go build
|
||||||
|
|
||||||
|
- name: docker
|
||||||
|
image: harbor.ntppool.org/ntppool/drone-kaniko:main
|
||||||
|
pull: always
|
||||||
|
volumes:
|
||||||
|
- name: deps
|
||||||
|
path: /go
|
||||||
|
settings:
|
||||||
|
repo: library/locationcode
|
||||||
|
registry: harbor.ntppool.org
|
||||||
|
auto_tag: true
|
||||||
|
tags: SHA7,${DRONE_SOURCE_BRANCH}
|
||||||
|
cache: true
|
||||||
|
username:
|
||||||
|
from_secret: harbor_library_username
|
||||||
|
password:
|
||||||
|
from_secret: harbor_library_password
|
21
Dockerfile
Normal file
21
Dockerfile
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
FROM golang:1.18-alpine3.15 AS build
|
||||||
|
RUN apk --no-cache add git
|
||||||
|
|
||||||
|
WORKDIR /go/src/
|
||||||
|
ADD . /go/src/
|
||||||
|
RUN go install -v ./...
|
||||||
|
|
||||||
|
|
||||||
|
FROM alpine:3.15
|
||||||
|
USER root
|
||||||
|
RUN apk --no-cache add ca-certificates
|
||||||
|
|
||||||
|
RUN addgroup lc && adduser -D -G lc lc
|
||||||
|
WORKDIR /
|
||||||
|
COPY --from=build /go/bin/locationcode /bin/
|
||||||
|
|
||||||
|
USER lc
|
||||||
|
|
||||||
|
RUN mkdir /tmp/data
|
||||||
|
|
||||||
|
CMD ["/bin/locationcode", "-data-dir=/tmp/data"]
|
159
airports.go
Normal file
159
airports.go
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/golang/geo/s2"
|
||||||
|
alphafoxtrot "github.com/grumpypixel/go-airport-finder"
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Airport struct {
|
||||||
|
Name string
|
||||||
|
Code string
|
||||||
|
Distance float64
|
||||||
|
data *alphafoxtrot.Airport
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
var dataDir = flag.String("data-dir", "./data", "Data cache directory")
|
||||||
|
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
validateData(*dataDir)
|
||||||
|
|
||||||
|
finder := alphafoxtrot.NewAirportFinder()
|
||||||
|
|
||||||
|
// LoadOptions come with preset filepaths
|
||||||
|
options := alphafoxtrot.PresetLoadOptions(*dataDir)
|
||||||
|
|
||||||
|
// filter := alphafoxtrot.AirportTypeLarge | alphafoxtrot.AirportTypeMedium
|
||||||
|
filter := alphafoxtrot.AirportTypeRunways
|
||||||
|
|
||||||
|
// Load the data into memory
|
||||||
|
if err := finder.Load(options, filter); len(err) > 0 {
|
||||||
|
log.Println("errors:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
e := echo.New()
|
||||||
|
e.GET("/", func(c echo.Context) error {
|
||||||
|
return c.String(http.StatusOK, "location code service")
|
||||||
|
})
|
||||||
|
e.GET("/v1/code", func(c echo.Context) error {
|
||||||
|
|
||||||
|
countryISOCode := c.QueryParam("cc")
|
||||||
|
countryISOCode = strings.ToUpper(countryISOCode)
|
||||||
|
|
||||||
|
radiusString := c.QueryParam("radius")
|
||||||
|
|
||||||
|
var radiusKM int
|
||||||
|
if len(radiusString) > 0 {
|
||||||
|
radiusKM, _ = strconv.Atoi(radiusString)
|
||||||
|
}
|
||||||
|
|
||||||
|
if radiusKM < 10 {
|
||||||
|
radiusKM = 100
|
||||||
|
}
|
||||||
|
|
||||||
|
latitude, longitude, err := getLatLng(c)
|
||||||
|
if err != nil {
|
||||||
|
return c.String(http.StatusBadRequest, fmt.Sprintf("invalid lat or lng: %s", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
ipLocation := s2.LatLngFromDegrees(latitude, longitude)
|
||||||
|
|
||||||
|
maxResults := 100
|
||||||
|
radiusInMeters := float64(radiusKM) * 1000
|
||||||
|
airportsRaw := finder.FindNearestAirportsByCountry(countryISOCode, latitude, longitude, radiusInMeters, maxResults, filter)
|
||||||
|
|
||||||
|
airports := []*alphafoxtrot.Airport{}
|
||||||
|
for _, ap := range airportsRaw {
|
||||||
|
if len(ap.IATACode) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
airports = append(airports, ap)
|
||||||
|
}
|
||||||
|
|
||||||
|
llCache := map[int]s2.LatLng{}
|
||||||
|
for i, ap := range airports {
|
||||||
|
ll := s2.LatLngFromDegrees(ap.LatitudeDeg, ap.LongitudeDeg)
|
||||||
|
llCache[i] = ll
|
||||||
|
}
|
||||||
|
|
||||||
|
r := []*Airport{}
|
||||||
|
|
||||||
|
for i, airport := range airports {
|
||||||
|
// fmt.Printf("%d %s: %+v\n", i, airport.Name, airport)
|
||||||
|
|
||||||
|
code := strings.ToLower(airport.Country.ISOCode + airport.IATACode)
|
||||||
|
|
||||||
|
distance := float64(ipLocation.Distance(llCache[i])) * 6371.01
|
||||||
|
|
||||||
|
a := &Airport{
|
||||||
|
Name: airport.Name,
|
||||||
|
Code: code,
|
||||||
|
Distance: distance,
|
||||||
|
data: airport,
|
||||||
|
}
|
||||||
|
r = append(r, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Slice(r, func(i, j int) bool {
|
||||||
|
if r[i].data.Type == r[j].data.Type {
|
||||||
|
return r[i].Distance < r[j].Distance
|
||||||
|
}
|
||||||
|
return airports[i].Type < airports[j].Type
|
||||||
|
})
|
||||||
|
|
||||||
|
if len(r) > 10 {
|
||||||
|
r = r[0:10]
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("got %d airports, filtered to %d, returning %d\n", len(airportsRaw), len(airports), len(r))
|
||||||
|
|
||||||
|
return c.JSON(http.StatusOK, r)
|
||||||
|
})
|
||||||
|
|
||||||
|
e.Logger.Fatal(e.Start(":8000"))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateData(dataDir string) {
|
||||||
|
downloadFiles := false
|
||||||
|
for _, filename := range alphafoxtrot.OurAirportsFiles {
|
||||||
|
filepath := path.Join(dataDir, filename)
|
||||||
|
if _, err := os.Stat(filepath); os.IsNotExist(err) {
|
||||||
|
downloadFiles = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if downloadFiles {
|
||||||
|
fmt.Println("Downloading CSV files from OurAirports.com...")
|
||||||
|
alphafoxtrot.DownloadDatabase(dataDir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getLatLng(c echo.Context) (float64, float64, error) {
|
||||||
|
latitudeStr := c.QueryParam("lat") // 37.3793
|
||||||
|
longitudeStr := c.QueryParam("lng") // -122.12
|
||||||
|
|
||||||
|
latitude, err := strconv.ParseFloat(latitudeStr, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, err
|
||||||
|
}
|
||||||
|
longitude, err := strconv.ParseFloat(longitudeStr, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return latitude, longitude, nil
|
||||||
|
}
|
22
go.mod
Normal file
22
go.mod
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
module go.askask.com/locationcode
|
||||||
|
|
||||||
|
go 1.18
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/golang/geo v0.0.0-20210211234256-740aa86cb551
|
||||||
|
github.com/grumpypixel/go-airport-finder v0.0.0-20210902211810-793a4fb1490b
|
||||||
|
github.com/labstack/echo/v4 v4.7.2
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/grumpypixel/go-webget v0.0.1 // indirect
|
||||||
|
github.com/labstack/gommon v0.3.1 // indirect
|
||||||
|
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||||
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
|
github.com/valyala/fasttemplate v1.2.1 // indirect
|
||||||
|
golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29 // indirect
|
||||||
|
golang.org/x/net v0.0.0-20220407224826-aac1ed45d8e3 // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20220406163625-3f8b81556e12 // indirect
|
||||||
|
golang.org/x/text v0.3.7 // indirect
|
||||||
|
)
|
44
go.sum
Normal file
44
go.sum
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 h1:gtexQ/VGyN+VVFRXSFiguSNcXmS6rkKT+X7FdIrTtfo=
|
||||||
|
github.com/golang/geo v0.0.0-20210211234256-740aa86cb551/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
|
||||||
|
github.com/grumpypixel/go-airport-finder v0.0.0-20210902211810-793a4fb1490b h1:CAT7j8NnDTijm+Mqc49PowzRwffiQwoNTdacBtAaPac=
|
||||||
|
github.com/grumpypixel/go-airport-finder v0.0.0-20210902211810-793a4fb1490b/go.mod h1:VSzLdQ8TugVDF/ZqngnVa/4budj2JLbC3spdz4eKEd4=
|
||||||
|
github.com/grumpypixel/go-webget v0.0.0-20210513194017-df576311f21d h1:ZD475Db8FZRfptdzpvWiAQPRkElVrITDmg7yiTN+vk0=
|
||||||
|
github.com/grumpypixel/go-webget v0.0.0-20210513194017-df576311f21d/go.mod h1:TZ3kzdKP644McT9EqfvX6vRcnoKxAGNJVbUGfDCgbpA=
|
||||||
|
github.com/grumpypixel/go-webget v0.0.1 h1:JByEaxRKMK3ACvARJCMva1Tb+mKmZPpIDF9gcgf42OU=
|
||||||
|
github.com/grumpypixel/go-webget v0.0.1/go.mod h1:TZ3kzdKP644McT9EqfvX6vRcnoKxAGNJVbUGfDCgbpA=
|
||||||
|
github.com/labstack/echo/v4 v4.7.2 h1:Kv2/p8OaQ+M6Ex4eGimg9b9e6icoxA42JSlOR3msKtI=
|
||||||
|
github.com/labstack/echo/v4 v4.7.2/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks=
|
||||||
|
github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o=
|
||||||
|
github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
|
||||||
|
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||||
|
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
|
||||||
|
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||||
|
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||||
|
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||||
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||||
|
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||||
|
github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
|
||||||
|
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||||
|
golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29 h1:tkVvjkPTB7pnW3jnid7kNyAMPVWllTNOf/qKDze4p9o=
|
||||||
|
golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
|
golang.org/x/net v0.0.0-20220407224826-aac1ed45d8e3 h1:EN5+DfgmRMvRUrMGERW2gQl3Vc+Z7ZMnI/xdEpPSf0c=
|
||||||
|
golang.org/x/net v0.0.0-20220407224826-aac1ed45d8e3/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||||
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220406163625-3f8b81556e12 h1:QyVthZKMsyaQwBTJE04jdNN0Pp5Fn9Qga0mrgxyERQM=
|
||||||
|
golang.org/x/sys v0.0.0-20220406163625-3f8b81556e12/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||||
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
Loading…
x
Reference in New Issue
Block a user