tzf

package module
v1.0.6 Latest Latest
Warning

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

Go to latest
Published: Apr 27, 2024 License: MIT Imports: 16 Imported by: 0

README

TZF: a fast timezone finder for Go. Go Reference codecov

no_gc gc

TZF is a fast timezone finder package designed for Go. It allows you to quickly find the timezone for a given latitude and longitude, making it ideal for geo queries and services such as weather forecast APIs. With optimized performance and two different data options, TZF is a powerful tool for any Go developer's toolkit.


[!NOTE]

Here are some language or server which built with tzf or it's other language bindings:

Language or Sever Link Note
Go Alfex4936/tzf
Ruby HarlemSquirrel/tzf-rb
Rust ringsaturn/tzf-rs
Python ringsaturn/tzfpy
HTTP API ringsaturn/tzf-server build with tzf
HTTP API racemap/rust-tz-service build with tzf-rs
Redis Server ringsaturn/tzf-server build with tzf
Redis Server ringsaturn/redizone build with tzf-rs

Quick Start

To start using TZF in your Go project, you first need to install the package:

go get github.com/Alfex4936/tzf

Then, you can use the following code to locate:

// Use about 150MB memory for init, and 60MB after GC.
package main

import (
	"fmt"

	"github.com/Alfex4936/tzf"
)

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

If you require a query result that is 100% accurate, use the following to locate:

// Use about 900MB memory for init, and 660MB after GC.
package main

import (
	"fmt"

	"github.com/Alfex4936/tzf"
	tzfrel "github.com/ringsaturn/tzf-rel"
	"github.com/Alfex4936/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))
}
Best Practice

It's expensive to init tzf's Finder/FuzzyFinder/DefaultFinder, please consider reuse it or as a global var. Below is a global var example:

package main

import (
	"fmt"

	"github.com/Alfex4936/tzf"
)

var f tzf.F

func init() {
	var err error
	f, err = tzf.NewDefaultFinder()
	if err != nil {
		panic(err)
	}
}

func main() {
	fmt.Println(f.GetTimezoneName(116.3883, 39.9289))
	fmt.Println(f.GetTimezoneName(-73.935242, 40.730610))
}

CLI Tool

In addition to using TZF as a library in your Go projects, you can also use the tzf command-line interface (CLI) tool to quickly get the timezone name for a set of coordinates. To use the CLI tool, you first need to install it using the following command:

go install github.com/Alfex4936/tzf/cmd/tzf@latest

Once installed, you can use the tzf command followed by the latitude and longitude values to get the timezone name:

tzf -lng 116.3883 -lat 39.9289

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

View Source
var ErrNoTimezoneFound = errors.New("tzf: no timezone found")

Functions

func SetDropPBTZ

func SetDropPBTZ(opt *Option)

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

Types

type DefaultFinder

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 (*DefaultFinder) DataVersion

func (f *DefaultFinder) DataVersion() string

func (*DefaultFinder) GetTimezoneName

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

Optimized GetTimezoneName considers initial direct lookups before falling back to concurrent offset checks

Example
package main

import (
	"fmt"

	"github.com/Alfex4936/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) GetTimezoneNames

func (f *DefaultFinder) GetTimezoneNames(lng float64, lat float64) ([]string, error)
Example
package main

import (
	"fmt"

	"github.com/Alfex4936/tzf"
)

func main() {
	finder, err := tzf.NewDefaultFinder()
	if err != nil {
		panic(err)
	}
	fmt.Println(finder.GetTimezoneNames(87.6168, 43.8254))
}
Output:

[Asia/Shanghai Asia/Urumqi] <nil>

func (*DefaultFinder) TimezoneNames

func (f *DefaultFinder) TimezoneNames() []string
Example
package main

import (
	"fmt"

	"github.com/Alfex4936/tzf"
)

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

type F

type F interface {
	GetTimezoneName(lng float64, lat float64) string
	GetTimezoneNames(lng float64, lat float64) ([]string, error)
	TimezoneNames() []string
	DataVersion() string
}

func NewDefaultFinder

func NewDefaultFinder() (F, error)

func NewFinderFromCompressed

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

func NewFinderFromPB

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

func NewFinderFromRawJSON

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

func NewFuzzyFinderFromPB

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

type Finder

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

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

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

func (*Finder) DataVersion

func (f *Finder) DataVersion() string

func (*Finder) GetTimezoneName

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

GetTimezoneName will use alphabet order and return first matched result.

Example
package main

import (
	"fmt"

	"github.com/Alfex4936/tzf"
	"github.com/Alfex4936/tzf/pb"

	tzfrellite "github.com/ringsaturn/tzf-rel-lite"
	"google.golang.org/protobuf/proto"
)

func main() {
	input := &pb.Timezones{}
	if err := proto.Unmarshal(tzfrellite.LiteData, input); err != nil {
		panic(err)
	}
	finder, _ := tzf.NewFinderFromPB(input)
	fmt.Println(finder.GetTimezoneName(116.6386, 40.0786))
}
Output:

Asia/Shanghai

func (*Finder) GetTimezoneName2 added in v1.0.4

func (f *Finder) GetTimezoneName2(lng, lat float64) string

func (*Finder) GetTimezoneNames

func (f *Finder) GetTimezoneNames(lng float64, lat float64) ([]string, error)
Example
package main

import (
	"fmt"

	"github.com/Alfex4936/tzf"
	"github.com/Alfex4936/tzf/pb"

	tzfrellite "github.com/ringsaturn/tzf-rel-lite"
	"google.golang.org/protobuf/proto"
)

func main() {
	input := &pb.Timezones{}
	if err := proto.Unmarshal(tzfrellite.LiteData, input); err != nil {
		panic(err)
	}
	finder, _ := tzf.NewFinderFromPB(input)
	fmt.Println(finder.GetTimezoneNames(87.6168, 43.8254))
}
Output:

[Asia/Shanghai Asia/Urumqi] <nil>

func (*Finder) IsKoreaTimezone added in v1.0.6

func (f *Finder) IsKoreaTimezone(lng float64, lat float64) bool

IsKoreaTimezone will check if the point is in the timezone of South Korea. (Asia/Seoul)

func (*Finder) TimezoneNames

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

type FuzzyFinder

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

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

func (*FuzzyFinder) DataVersion

func (f *FuzzyFinder) DataVersion() string

func (*FuzzyFinder) GetTimezoneName

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

import (
	"fmt"

	"github.com/Alfex4936/tzf"
	"github.com/Alfex4936/tzf/pb"

	tzfrellite "github.com/ringsaturn/tzf-rel-lite"
	"google.golang.org/protobuf/proto"
)

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

Asia/Shanghai

func (*FuzzyFinder) GetTimezoneNames

func (f *FuzzyFinder) GetTimezoneNames(lng float64, lat float64) ([]string, error)
Example
package main

import (
	"fmt"

	"github.com/Alfex4936/tzf"
	"github.com/Alfex4936/tzf/pb"

	tzfrellite "github.com/ringsaturn/tzf-rel-lite"
	"google.golang.org/protobuf/proto"
)

func main() {
	input := &pb.PreindexTimezones{}
	if err := proto.Unmarshal(tzfrellite.PreindexData, input); err != nil {
		panic(err)
	}
	finder, _ := tzf.NewFuzzyFinderFromPB(input)
	fmt.Println(finder.GetTimezoneNames(87.6168, 43.8254))
}
Output:

[Asia/Shanghai Asia/Urumqi] <nil>

func (*FuzzyFinder) TimezoneNames

func (f *FuzzyFinder) TimezoneNames() []string
Example
package main

import (
	"fmt"

	"github.com/Alfex4936/tzf"
	"github.com/Alfex4936/tzf/pb"

	tzfrellite "github.com/ringsaturn/tzf-rel-lite"
	"google.golang.org/protobuf/proto"
)

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

type Option

type Option struct {
	DropPBTZ bool
}

type OptionFunc

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
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