Working auth and photo json endpoint
Signed-off-by: Kris Nóva <kris@nivenly.com>
This commit is contained in:
parent
ef275f97f4
commit
e4323b6047
2032 changed files with 821464 additions and 52 deletions
160
vendor/gopkg.in/ugjka/go-tz.v2/tz/tz.go
generated
vendored
Normal file
160
vendor/gopkg.in/ugjka/go-tz.v2/tz/tz.go
generated
vendored
Normal file
|
@ -0,0 +1,160 @@
|
|||
// Package tz provides timezone lookup for a given location
|
||||
//
|
||||
// Features
|
||||
//
|
||||
// * The timezone shapefile is embedded in the build binary using go-bindata
|
||||
//
|
||||
// * Supports overlapping zones
|
||||
//
|
||||
// * You can load your own geojson shapefile if you want
|
||||
//
|
||||
// * Sub millisecond lookup even on old hardware
|
||||
//
|
||||
// Problems
|
||||
//
|
||||
// * The shapefile is simplified using a lossy method so it may be innacurate along the borders
|
||||
//
|
||||
// * This is purerly in-memory. Uses ~50MB of ram
|
||||
package tz
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"runtime/debug"
|
||||
)
|
||||
|
||||
func init() {
|
||||
load()
|
||||
}
|
||||
|
||||
func load() {
|
||||
g, err := gzip.NewReader(bytes.NewBuffer(tzShapeFile))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer g.Close()
|
||||
|
||||
if err := json.NewDecoder(g).Decode(&tzdata); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
buildCenterCache()
|
||||
debug.FreeOSMemory()
|
||||
}
|
||||
|
||||
var tzdata FeatureCollection
|
||||
|
||||
type centers map[string][]Point
|
||||
|
||||
var centerCache centers
|
||||
|
||||
// Point describes a location by Latitude and Longitude
|
||||
type Point struct {
|
||||
Lon float64
|
||||
Lat float64
|
||||
}
|
||||
|
||||
// ErrNoZoneFound is returned when a zone for the given point is not found in the shapefile
|
||||
var ErrNoZoneFound = errors.New("no corresponding zone found in shapefile")
|
||||
|
||||
// ErrOutOfRange is returned when latitude exceeds 90 degrees or longitude exceeds 180 degrees
|
||||
var ErrOutOfRange = errors.New("point's coordinates out of range")
|
||||
|
||||
// GetZone returns a slice of strings containing time zone id's for a given Point
|
||||
func GetZone(p Point) (tzid []string, err error) {
|
||||
if p.Lon > 180 || p.Lon < -180 || p.Lat > 90 || p.Lat < -90 {
|
||||
return nil, ErrOutOfRange
|
||||
}
|
||||
var id string
|
||||
for _, v := range tzdata.Features {
|
||||
if v.Properties.Tzid == "" {
|
||||
continue
|
||||
}
|
||||
id = v.Properties.Tzid
|
||||
polys := v.Geometry.Coordinates
|
||||
bboxes := v.Geometry.BoundingBoxes
|
||||
for i := 0; i < len(polys); i++ {
|
||||
//Check bounding box first
|
||||
if !inBoundingBox(bboxes[i], &p) {
|
||||
continue
|
||||
}
|
||||
if polygon(polys[i]).contains(&p) {
|
||||
tzid = append(tzid, id)
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(tzid) > 0 {
|
||||
return tzid, nil
|
||||
}
|
||||
return getClosestZone(&p)
|
||||
}
|
||||
|
||||
func distanceFrom(p1, p2 *Point) float64 {
|
||||
d0 := (p1.Lon - p2.Lon)
|
||||
d1 := (p1.Lat - p2.Lat)
|
||||
return math.Sqrt(d0*d0 + d1*d1)
|
||||
}
|
||||
|
||||
func getClosestZone(point *Point) (tzid []string, err error) {
|
||||
mindist := math.Inf(1)
|
||||
var winner string
|
||||
for id, v := range centerCache {
|
||||
for _, p := range v {
|
||||
tmp := distanceFrom(&p, point)
|
||||
if tmp < mindist {
|
||||
mindist = tmp
|
||||
winner = id
|
||||
}
|
||||
}
|
||||
}
|
||||
// Limit search radius
|
||||
if mindist > 2.0 {
|
||||
return getNauticalZone(point)
|
||||
}
|
||||
return append(tzid, winner), nil
|
||||
}
|
||||
|
||||
func getNauticalZone(point *Point) (tzid []string, err error) {
|
||||
z := point.Lon / 7.5
|
||||
z = (math.Abs(z) + 1) / 2
|
||||
z = math.Floor(z)
|
||||
if z == 0 {
|
||||
return append(tzid, "Etc/GMT"), nil
|
||||
}
|
||||
if point.Lon < 0 {
|
||||
return append(tzid, fmt.Sprintf("Etc/GMT+%.f", z)), nil
|
||||
}
|
||||
return append(tzid, fmt.Sprintf("Etc/GMT-%.f", z)), nil
|
||||
}
|
||||
|
||||
//BuildCenterCache builds centers for polygons
|
||||
func buildCenterCache() {
|
||||
centerCache = make(centers)
|
||||
var tzid string
|
||||
for _, v := range tzdata.Features {
|
||||
if v.Properties.Tzid == "" {
|
||||
continue
|
||||
}
|
||||
tzid = v.Properties.Tzid
|
||||
for _, poly := range v.Geometry.Coordinates {
|
||||
centerCache[tzid] = append(centerCache[tzid], polygon(poly).centroid())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// LoadGeoJSON loads a custom GeoJSON shapefile from a Reader
|
||||
func LoadGeoJSON(r io.Reader) error {
|
||||
tzdata = FeatureCollection{}
|
||||
err := json.NewDecoder(r).Decode(&tzdata)
|
||||
if err != nil {
|
||||
load()
|
||||
return err
|
||||
}
|
||||
buildCenterCache()
|
||||
debug.FreeOSMemory()
|
||||
return nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue