A self-contained geo lookup library / binary / server for Rust / JS (via WASM) (free server) using data from the Natural Earth and OpenStreetMap datasets.
The server is deployed to four regions across the globe, and is available at tz.twitchax.com. Each region is currently capable of supporting around 8,000 RPS, and is deployed to the following regions: sea, iad, ams, hkg.
In addition, the server will now generally attempt to not break backwards compatibility within an api version. This means that the server will (attempt to) not change the response format for a given api version, and will (attempt to) not remove any fields from the response. This does not mean that the server will not add fields to the response, but it will (attempt to) not remove them.
Requests take the form of http://tz.twitchax.com/api/v1/osm/tz/{lng}/{lat}
. You can also check out the api docs to explore other endpoints and versioning strategy.
Example request:
$ curl http://tz.twitchax.com/api/v1/osm/tz/30/30
[{"id":12,"identifier":"Africa/Cairo","shortIdentifier":"EEST","offset":"UTC+03:00","rawOffset":10800,"rawBaseOffset":7200,"rawDstOffset":3600,"zone":3.0,"currentTime":"2023-07-25T23:39:59.385469400+03:00"}]
HTTPS is also available, but is not recommended due to the performance overhead for the client and the server, and the lack of sensitive data being transmitted.
Windows:
$ iwr https://github.com/twitchax/rtz/releases/latest/download/rtz_x86_64-pc-windows-gnu.zip
$ Expand-Archive rtz_x86_64-pc-windows-gnu.zip -DestinationPath C:\Users\%USERNAME%\AppData\Local\Programs\rtz
Mac OS (Apple Silicon):
$ curl -LO https://github.com/twitchax/rtz/releases/latest/download/rtz_aarch64-apple-darwin.zip
$ unzip rtz_aarch64-apple-darwin.zip -d /usr/local/bin
$ chmod a+x /usr/local/bin/rtz
Linux:
$ curl -LO https://github.com/twitchax/rtz/releases/latest/download/rtz_x86_64-unknown-linux-gnu.zip
$ unzip rtz_x86_64-unknown-linux-gnu.zip -d /usr/local/bin
$ chmod a+x /usr/local/bin/rtz
Cargo:
$ cargo install rtz
NPM:
$ npm install --save rtzweb
$ rtz
A tool to easily work with geo lookups via a binary, a library, or a server.
Usage: rtz [COMMAND]
Commands:
ned The Natural Earth Data dataset based operations
osm The OpenStreetMap dataset based operations
dump-geojson Resolve a timezone from a lng,lat pair using the OSM dataset
serve Serve the timezone API
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help
-V, --version Print version
$ rtz ned tz "-87.62,41.88"
Identifier: America/Chicago
UTC Offset: UTC-06:00
Offset Seconds: -21600
Description: Canada (almost all of Saskatchewan), Costa Rica, El Salvador, Ecuador (Galapagos Islands), Guatemala, Honduras, Mexico (most), Nicaragua,
DST Description: Canada (Manitoba), United States (Illinois, most of Texas)
wasmer run twitchax/rtz@latest -- ned tz 30,30
$ cargo install rtz --features web
$ rtz serve
$ docker run -it --rm -p 8082 twitchax/rtz
Add this to your Cargo.toml
:
[dependencies]
rtz = "*" #choose a version
use rtzlib::NedTimezone;
use rtzlib::CanPerformGeoLookup;
// Query a time zone for a given `(lng,lat)`.
assert_eq!(
NedTimezone::lookup(-121., 46.)[0]
.identifier
.as_ref()
.unwrap(),
"America/Los_Angeles"
);
The npm package is available here.
First, load the module as you would any other ES module.
import * as rtz from 'rtzweb/rtzlib.js';
Then, you can use the library similarly as you would in Rust.
let tz = rtz.getTimezoneNed(-121, 46);
tz.identifier; // "America/Los_Angeles"
The library and binary both support various feature flags. These are the available flags:
- Top-Level:
default = ["cli"]
full = ["tz-ned", "tz-osm", "admin-osm", "self-contained"]
- Datasets:
tz-ned
: enables the Natural Earth time zone dataset, and the associated produced library functions.tz-osm
: enables the OpenStreetMap time zone dataset, and the associated produced library functions.admin-osm
: enables the OpenStreetMap administrative dataset, and the associated produced library functions.
- Binary configuration:
cli
: enables the CLI features, and can be removed if only compiling the library.self-contained
: enables the self-contained features, which build with datasets embedded into the binary.double-precision
: usesf64
s everywhere forGeometry
andPolygon
data types, which is more accurate but fatter thanf32
s.unsimplified
: produces unsimplified data caches. Requires more binary / memory overhead, but is more accurate. Uses the level of detail from the original dataset. The default is to simplify to an epsilon of0.0001
(generally).extrasimplified
: produces extrasimplified data caches. Requires less binary / memory overhead, but is less accurate. This sets the simplification epsilon to0.01
(generally).owned-decode
: usesowned
instead ofborrow
for thedecode
feature of thebincode
crate. This increases memory footprint by not mapping the data directly from the binary, but is lessunsafe
-y / dark arts-y.
- Special Modifiers:
wasm
: enables the WASM features, and is required to build an NPM package viawasm-pack
, or producewasi
binaries.web = ["full"]
: enables theserve
subcommand, which starts a Rocket web server that can respond to time zone requests.
- Other Considerations:
wasm
/wasi
builds currently do not play nice withreqwest
andzip
, so thewasm
/wasi
builds require theself-contained
feature.
The last updates were made 2024.08.08. The data sources on that date were as follows:
- OSM Admin Data. This data is downloaded from the OSM planet file, and is then processed locally to extract the administrative boundaries.
- OSM TZ Data. This data is downloaded from the latest generated release of the timezone boundary builder, and is processed automatically by this code.
- NED TZ Data. This data is downloaded from the
master
branch of the NED vector repository, and is processed automatically by this code.
This implementation trades binary size for performance by employing an in-binary cache that improves average timezone resolution by about 96x, and worst-case resolution by about 10x. Average timezone lookup time is around 930 ns
using the OSM dataset, and around 460 ns
for the NED dataset. Worst-case lookup time is around 6 - 10 μs
.
On average, for random cities, the OSM dataset lookup time is around 1.5 μs
, and the NED dataset lookup time is around 400 ns
.
Below is the sample performance to resolve a time zone from a (lng,lat)
pair to one of the data centers using a concurrency of 1,000, achieving 8,000 RPS.
Below is the sample performance to resolve a time zone from a (lng,lat)
pair to one of the data centers using a concurrency of 100, achieving an average response time of 24 ms
.
cargo test --features web
cargo bench --features web
MIT