tzf

package module
v0.9.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 12, 2022 License: MIT Imports: 13 Imported by: 12

README

TZF: a timezone finder for Go&Python. Go Reference PyPI

Quick Start

Go
package main

import (
	"fmt"

	"github.com/ringsaturn/tzf"
)

func main() {
	finder, err := tzf.NewDefaultFinder()
	if err != nil {
		panic(err)
	}
	fmt.Println(finder.GetTimezoneName(116.6386, 40.0786))
}

If you need 100% accurate query result, use below to got a finder:

package main

import (
	"fmt"

	"github.com/ringsaturn/tzf"
	tzfrel "github.com/ringsaturn/tzf-rel"
	"github.com/ringsaturn/tzf/pb"
	"google.golang.org/protobuf/proto"
)

func main() {
	input := &pb.Timezones{}

	// Full data, about 83.5MB
	dataFile := tzfrel.FullData

	if err := proto.Unmarshal(dataFile, input); err != nil {
		panic(err)
	}
	finder, _ := tzf.NewFinderFromPB(input)
	fmt.Println(finder.GetTimezoneName(116.6386, 40.0786))
}
Python
pip install tzfpy
>>> from tzfpy import get_tz
>>> print(get_tz(121.4737, 31.2305))
Asia/Shanghai

Python binding source codes: https://github.com/ringsaturn/tzf/tree/main/python

CLI Tool
go install github.com/ringsaturn/tzf/cmd/tzf@latest
tzf -lng 116.3883 -lat 39.9289

Data

Original data download from https://github.com/evansiroky/timezone-boundary-builder.

Preprocessed probuf data can get from https://github.com/ringsaturn/tzf-rel which has Go's embed support.

tzf's data pipeline can de drew as:

graph TD
    Raw[GeoJSON from evansiroky/timezone-boundary-builder]
    Full[Full: Probuf based data]
    Lite[Lite: smaller of Full data]
    Compressed[Compressed: Lite compressed via Polyline]
    Preindex[Tile based data]

    Finder[Finder: Polygon Based Finder]
    FuzzyFinder[FuzzyFinder: Tile based Finder]
    DefaultFinder[DefaultFinder: combine FuzzyFinder and Compressed Finder]

    tzfpy[tzfpy: tzf's Python binding]

    Raw --> |cmd/geojson2tzpb|Full
    Full --> |cmd/reducetzpb|Lite
    Lite --> |cmd/compresstzpb|Compressed
    Lite --> |cmd/preindextzpb|Preindex

    Full --> |tzf.NewFinderFromPB|Finder
    Lite --> |tzf.NewFinderFromPB|Finder
    Compressed --> |tzf.NewFinderFromCompressed|Finder --> |tzf.NewDefaultFinder|DefaultFinder
    Preindex --> |tzf.NewFuzzyFinderFromPB|FuzzyFinder --> |tzf.NewDefaultFinder|DefaultFinder

    DefaultFinder --> tzfpy

The full data(~80MB) could work anywhere but requires more memory usage.

The lite data(~10MB) doesn't work well in some edge places.

You can see points that results diff in this page.

If a little longer init time is acceptable, the compressed data(~5MB) which come from lite data will be more friendly for binary distribution.

The preindex data(~1.78MB) are many tiles. It's used inside the DefaultFinder, which built on FuzzyFinder, to reduce raycasting algorithm execution times.

Performance

Benchmark run version https://github.com/ringsaturn/tzf/releases/tag/v0.9.0

goos: darwin
goarch: amd64
pkg: github.com/ringsaturn/tzf
cpu: Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
BenchmarkDefaultFinder_GetTimezoneName_Random_WorldCities-16              731966              1737 ns/op
BenchmarkFuzzyFinder_GetTimezoneName_Random_WorldCities-16               1608507               734.9 ns/op
BenchmarkGetTimezoneName-16                                               260023              4646 ns/op
BenchmarkGetTimezoneNameAtEdge-16                                         234446              5178 ns/op
BenchmarkGetTimezoneName_Random_WorldCities-16                            178764              6571 ns/op
BenchmarkFullFinder_GetTimezoneName-16                                    236419              5088 ns/op
BenchmarkFullFinder_GetTimezoneNameAtEdge-16                              225300              5470 ns/op
BenchmarkFullFinder_GetTimezoneName_Random_WorldCities-16                 127683              8070 ns/op
PASS
ok      github.com/ringsaturn/tzf       18.869s

Thanks

Documentation

Overview

Package tzf is a package convert (lng,lat) to timezone.

Inspired by timezonefinder https://github.com/jannikmi/timezonefinder, fast python package for finding the timezone of any point on earth (coordinates) offline.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func SetDropPBTZ added in v0.9.2

func SetDropPBTZ(opt *Option)

SetDropPBTZ will make Finder not save github.com/ringsaturn/tzf/pb.Timezone in memory

Types

type DefaultFinder added in v0.9.0

type DefaultFinder struct {
	// contains filtered or unexported fields
}

DefaultFinder is a finder impl combine both FuzzyFinder and Finder.

It's designed for performance first and allow some not so correct return at some area.

func NewDefaultFinder added in v0.9.0

func NewDefaultFinder() (*DefaultFinder, error)

func (*DefaultFinder) GetTimezoneName added in v0.9.0

func (f *DefaultFinder) GetTimezoneName(lng float64, lat float64) string
Example
package main

import (
	"fmt"

	"github.com/ringsaturn/tzf"
)

func main() {
	finder, err := tzf.NewDefaultFinder()
	if err != nil {
		panic(err)
	}
	fmt.Println(finder.GetTimezoneName(116.6386, 40.0786))
}
Output:

Asia/Shanghai

func (*DefaultFinder) TimezoneNames added in v0.9.0

func (f *DefaultFinder) TimezoneNames() []string

type Finder

type Finder struct {
	// contains filtered or unexported fields
}

Finder is based on point-in-polygon search algo.

Memeory will use about 100MB if lite data and 1G if full data. Performance is very stable and very accuate.

func NewFinderFromCompressed added in v0.8.0

func NewFinderFromCompressed(input *pb.CompressedTimezones, opts ...OptionFunc) (*Finder, error)

func NewFinderFromPB

func NewFinderFromPB(input *pb.Timezones, opts ...OptionFunc) (*Finder, error)

func NewFinderFromRawJSON added in v0.2.0

func NewFinderFromRawJSON(input *convert.BoundaryFile, opts ...OptionFunc) (*Finder, error)

func (*Finder) GetTimezone added in v0.3.0

func (f *Finder) GetTimezone(lng float64, lat float64) (*pb.Timezone, error)

func (*Finder) GetTimezoneLoc

func (f *Finder) GetTimezoneLoc(lng float64, lat float64) (*time.Location, error)
Example
package main

import (
	"fmt"

	"github.com/ringsaturn/tzf"

	tzfrel "github.com/ringsaturn/tzf-rel"
	"github.com/ringsaturn/tzf/pb"
	"google.golang.org/protobuf/proto"
)

func main() {
	input := &pb.Timezones{}

	// Lite data, about 16.7MB
	dataFile := tzfrel.LiteData

	// Full data, about 83.5MB
	// dataFile := tzfrel.FullData

	if err := proto.Unmarshal(dataFile, input); err != nil {
		panic(err)
	}
	finder, _ := tzf.NewFinderFromPB(input)
	fmt.Println(finder.GetTimezoneLoc(116.6386, 40.0786))
}
Output:

Asia/Shanghai <nil>

func (*Finder) GetTimezoneName

func (f *Finder) GetTimezoneName(lng float64, lat float64) string
Example
package main

import (
	"fmt"

	"github.com/ringsaturn/tzf"

	tzfrel "github.com/ringsaturn/tzf-rel"
	"github.com/ringsaturn/tzf/pb"
	"google.golang.org/protobuf/proto"
)

func main() {
	input := &pb.Timezones{}

	// Lite data, about 16.7MB
	dataFile := tzfrel.LiteData

	// Full data, about 83.5MB
	// dataFile := tzfrel.FullData

	if err := proto.Unmarshal(dataFile, input); err != nil {
		panic(err)
	}
	finder, _ := tzf.NewFinderFromPB(input)
	fmt.Println(finder.GetTimezoneName(116.6386, 40.0786))
}
Output:

Asia/Shanghai

func (*Finder) GetTimezoneShapeByName added in v0.5.0

func (f *Finder) GetTimezoneShapeByName(name string) (*pb.Timezone, error)
Example
package main

import (
	"fmt"

	"github.com/ringsaturn/tzf"

	tzfrel "github.com/ringsaturn/tzf-rel"
	"github.com/ringsaturn/tzf/pb"
	"google.golang.org/protobuf/proto"
)

func main() {
	input := &pb.Timezones{}

	// Lite data, about 16.7MB
	dataFile := tzfrel.LiteData

	if err := proto.Unmarshal(dataFile, input); err != nil {
		panic(err)
	}
	finder, _ := tzf.NewFinderFromPB(input)
	pbtz, err := finder.GetTimezoneShapeByName("Asia/Shanghai")
	fmt.Printf("%v %v\n", pbtz.Name, err)
}
Output:

Asia/Shanghai <nil>

func (*Finder) GetTimezoneShapeByShift added in v0.5.0

func (f *Finder) GetTimezoneShapeByShift(shift int) ([]*pb.Timezone, error)
Example
package main

import (
	"fmt"
	"strings"

	"sort"

	"github.com/ringsaturn/tzf"

	tzfrel "github.com/ringsaturn/tzf-rel"
	"github.com/ringsaturn/tzf/pb"
	"google.golang.org/protobuf/proto"
)

func main() {
	input := &pb.Timezones{}

	// Lite data, about 16.7MB
	dataFile := tzfrel.LiteData

	if err := proto.Unmarshal(dataFile, input); err != nil {
		panic(err)
	}
	finder, _ := tzf.NewFinderFromPB(input)
	pbtzs, _ := finder.GetTimezoneShapeByShift(28800)

	pbnames := make([]string, 0)
	for _, pbtz := range pbtzs {
		pbnames = append(pbnames, pbtz.Name)
	}
	sort.Strings(pbnames)

	fmt.Println(strings.Join(pbnames, ","))
}
Output:

Asia/Brunei,Asia/Choibalsan,Asia/Hong_Kong,Asia/Irkutsk,Asia/Kuala_Lumpur,Asia/Kuching,Asia/Macau,Asia/Makassar,Asia/Manila,Asia/Shanghai,Asia/Singapore,Asia/Taipei,Asia/Ulaanbaatar,Australia/Perth,Etc/GMT-8

func (*Finder) TimezoneNames added in v0.6.2

func (f *Finder) TimezoneNames() []string

type FuzzyFinder added in v0.9.0

type FuzzyFinder struct {
	// contains filtered or unexported fields
}

FuzzyFinder use a tile map to store timezone name. Data are made by github.com/ringsaturn/tzf/cmd/preindextzpb which powerd by github.com/ringsaturn/tzf/preindex.PreIndexTimezones.

func NewFuzzyFinderFromPB added in v0.9.0

func NewFuzzyFinderFromPB(input *pb.PreindexTimezones) (*FuzzyFinder, error)

func (*FuzzyFinder) GetTimezoneName added in v0.9.0

func (f *FuzzyFinder) GetTimezoneName(lng float64, lat float64) string
Example
package main

import (
	"fmt"

	"github.com/ringsaturn/tzf"

	tzfrel "github.com/ringsaturn/tzf-rel"
	"github.com/ringsaturn/tzf/pb"
	"google.golang.org/protobuf/proto"
)

func main() {
	input := &pb.PreindexTimezones{}
	if err := proto.Unmarshal(tzfrel.PreindexData, input); err != nil {
		panic(err)
	}
	finder, _ := tzf.NewFuzzyFinderFromPB(input)
	fmt.Println(finder.GetTimezoneName(116.6386, 40.0786))
}
Output:

Asia/Shanghai

type Option added in v0.9.2

type Option struct {
	DropPBTZ bool
}

type OptionFunc added in v0.9.2

type OptionFunc = func(opt *Option)

Directories

Path Synopsis
cmd
compresstzpb
CLI tool to reduce polygon filesize
CLI tool to reduce polygon filesize
geojson2tzpb
CLI tool to convert GeoJSON based Timezone boundary to tzf's Probuf format.
CLI tool to convert GeoJSON based Timezone boundary to tzf's Probuf format.
preindextzpb
CLI tool to preindex timezone shape.
CLI tool to preindex timezone shape.
reducetzpb
CLI tool to reduce polygon filesize
CLI tool to reduce polygon filesize
tzf
tzf-cli tool for local query.
tzf-cli tool for local query.
Package preindex
Package preindex
python
tzfpy
TZF's Python binding
TZF's Python binding
Package reduce could reduce Polygon size both polygon lines and float precise.
Package reduce could reduce Polygon size both polygon lines and float precise.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL