xref: /aosp_15_r20/external/timezone-boundary-builder/README.md (revision f0df97945b4fdddd066170b120f192941b8d7fbf)
1*f0df9794SNeil Fuller# Timezone Boundary Builder
2*f0df9794SNeil Fuller
3*f0df9794SNeil FullerThe goal of this project is to produce a shapefile with the boundaries of the world's timezones using OpenStreetMap data.
4*f0df9794SNeil Fuller
5*f0df9794SNeil Fuller<p align="center"><img src="2020d.png" /></p>
6*f0df9794SNeil Fuller
7*f0df9794SNeil Fuller[![Github downloads for all releases](https://img.shields.io/github/downloads/evansiroky/timezone-boundary-builder/total.svg)](https://tooomm.github.io/github-release-stats/?username=evansiroky&repository=timezone-boundary-builder)  [![GitHub release](https://img.shields.io/github/release/evansiroky/timezone-boundary-builder.svg)](https://github.com/evansiroky/timezone-boundary-builder/releases/latest)
8*f0df9794SNeil Fuller
9*f0df9794SNeil Fuller
10*f0df9794SNeil Fuller## Shapefiles and data
11*f0df9794SNeil Fuller
12*f0df9794SNeil FullerThe shapefiles are available for download in this project's [releases](https://github.com/evansiroky/timezone-boundary-builder/releases). As of release 2018d shapefiles are available with or without oceans.  Each shape or geojson object has a single attribute or property respectively called `tzid`.  The tzid corresponds to the timezone name as defined in the [timezone database](https://www.iana.org/time-zones) (for example: `America/Los_Angeles` or `Asia/Shanghai`).
13*f0df9794SNeil Fuller
14*f0df9794SNeil FullerThis project aims to stay up-to-date with all of the currently valid timezones that are defined in the timezone database.  This project also will attempt to provide the most accurate possible boundaries of timezones according to community input.
15*f0df9794SNeil Fuller
16*f0df9794SNeil FullerThe underlying data is downloaded from [OpenStreetMap](http://www.openstreetmap.org/) via the [overpass turbo API](http://overpass-turbo.eu/).  Various boundaries are assembled together to produce each zone with various geographic operations.  In numerous edge cases arbitrary boundaries get created in various zones which are noted in the `timezones.json` file.
17*f0df9794SNeil Fuller
18*f0df9794SNeil FullerTo maintain consistency with the timezone database, this project will only create a new release after the timezone database creates a new release.  If there are no new timezones created or deleted in a timezone database release, then this project will only create a release if there have been changes performed to the boundary definitions of an existing zone within this project.
19*f0df9794SNeil Fuller
20*f0df9794SNeil Fuller## Lookup Libraries
21*f0df9794SNeil Fuller
22*f0df9794SNeil FullerA few common languages already have libraries with an API that can be used to lookup the timezone name at a particular GPS coordinate.  Here are some libraries that use the data produced by timezone-boundary-builder:
23*f0df9794SNeil Fuller
24*f0df9794SNeil Fuller| Library | Language |
25*f0df9794SNeil Fuller| -- | -- |
26*f0df9794SNeil Fuller| [ZoneDetect](https://github.com/BertoldVdb/ZoneDetect) | C |
27*f0df9794SNeil Fuller| [go-tz](https://github.com/ugjka/go-tz) | Go |
28*f0df9794SNeil Fuller| [timezoneLookup](https://github.com/evanoberholster/timezoneLookup) | Go |
29*f0df9794SNeil Fuller| [TimeZoneMap](https://github.com/dustin-johnson/timezonemap) | Java & Android |
30*f0df9794SNeil Fuller| [Timeshape](https://github.com/RomanIakovlev/timeshape) | Java |
31*f0df9794SNeil Fuller| [node-geo-tz](https://github.com/evansiroky/node-geo-tz/) | JavaScript (node.js only) |
32*f0df9794SNeil Fuller| [timespace](https://github.com/mapbox/timespace) | JavaScript (node.js and in browser) |
33*f0df9794SNeil Fuller| [tz-lookup](https://github.com/darkskyapp/tz-lookup-oss) | JavaScript (node.js and in browser) |
34*f0df9794SNeil Fuller| [GeoTimezone](https://github.com/mj1856/GeoTimeZone) | .NET |
35*f0df9794SNeil Fuller| [Geo-Timezone](https://github.com/minube/geo-timezone) | php |
36*f0df9794SNeil Fuller| [timezonefinder](https://github.com/MrMinimal64/timezonefinder) | Python |
37*f0df9794SNeil Fuller| [lutz](https://github.com/ateucher/lutz) | R |
38*f0df9794SNeil Fuller| [wheretz](https://github.com/zverok/wheretz) | Ruby |
39*f0df9794SNeil Fuller
40*f0df9794SNeil FullerAnother common way to use the data for lookup purposes is to load the shapefile into a spatially-aware database.  See this [blog post](https://simonwillison.net/2017/Dec/12/location-time-zone-api/) for an example of how that can be done.
41*f0df9794SNeil Fuller
42*f0df9794SNeil Fuller## Running the script
43*f0df9794SNeil Fuller
44*f0df9794SNeil FullerIf the data in the releases are not sufficiently recent or you want to build the latest from master, it is possible to run the script to generate the timezones.  However, due to the ever-changing nature of OpenStreetMap, the script should be considered unstable.  The script frequently breaks when unexpected data is received or changes in OpenStreetMap cause validation issues.  Please see the [troubleshooting guide](https://github.com/evansiroky/timezone-boundary-builder/wiki/Troubleshooting) for help with common errors.
45*f0df9794SNeil Fuller
46*f0df9794SNeil Fuller**Run the script to generate timezones for all timezones.**
47*f0df9794SNeil Fuller
48*f0df9794SNeil Fuller```shell
49*f0df9794SNeil Fullernode --max-old-space-size=8192 index.js
50*f0df9794SNeil Fuller```
51*f0df9794SNeil Fuller
52*f0df9794SNeil Fuller**Run the script to generate timezones for only specified timezones.**
53*f0df9794SNeil Fuller
54*f0df9794SNeil Fuller```shell
55*f0df9794SNeil Fullernode --max-old-space-size=8192 index.js --included_zones America/New_York America/Chicago
56*f0df9794SNeil Fuller```
57*f0df9794SNeil Fuller
58*f0df9794SNeil Fuller**Run the script to generate timezones while excluding specified timezones.**
59*f0df9794SNeil Fuller
60*f0df9794SNeil Fuller```shell
61*f0df9794SNeil Fullernode --max-old-space-size=8192 index.js --excluded_zones America/New_York America/Chicago
62*f0df9794SNeil Fuller```
63*f0df9794SNeil Fuller
64*f0df9794SNeil Fuller**Run the script with custom working / output directories.**
65*f0df9794SNeil Fuller
66*f0df9794SNeil Fullertimezone-boundary-builder downloads boundaries from OpenStreetMap and places them in the `./downloads` directory by default. It generates output files in the `./dist` directory by default.
67*f0df9794SNeil Fuller
68*f0df9794SNeil FullerIf you want to use different directories, you can do so with the `--downloads_dir` and `--dist_dir` flags.
69*f0df9794SNeil Fuller
70*f0df9794SNeil Fuller```shell
71*f0df9794SNeil Fullernode --max-old-space-size=8192 index.js --downloads_dir ./downloads2 --dist_dir ./dist2
72*f0df9794SNeil Fuller```
73*f0df9794SNeil Fuller
74*f0df9794SNeil Fuller**Other command line flags**
75*f0df9794SNeil Fuller
76*f0df9794SNeil FullerOther command line flags:
77*f0df9794SNeil Fuller
78*f0df9794SNeil Fuller  + `--help` - show some basic usage information
79*f0df9794SNeil Fuller  + `--skip_analyze_diffs` - do not analyze differences between the current output and another version
80*f0df9794SNeil Fuller  + `--skip_shapefile` - do not create the shapefile from the geojson file
81*f0df9794SNeil Fuller  + `--skip_validation` - do not validate the time zone boundaries
82*f0df9794SNeil Fuller  + `--skip_zip` - do not zip the generated geojson files
83*f0df9794SNeil Fuller
84*f0df9794SNeil Fuller
85*f0df9794SNeil Fuller### What the script does
86*f0df9794SNeil Fuller
87*f0df9794SNeil FullerThere are three config files that describe the boundary building process.  The `osmBoundarySources.json` file lists all of the needed boundaries to extract via queries to the Overpass API.  The `timezones.json` file lists all of the timezones and various operations to perform to build the boundaries.  The `expectedZoneOverlaps.json` file lists all timezones that are allowed to overlap each other and the acceptable bounds of a particular overlap.
88*f0df9794SNeil Fuller
89*f0df9794SNeil FullerThe `index.js` file downloads all of the required geometries, builds the specified geometries, validates that there aren't large areas of overlap (other than those that are expected), analyzes the difference between the current output and the last release, outputs one huge geojson file, and finally zips up the geojson file using the `zip` cli and also converts the geojson to a shapefile using the `ogr2ogr` cli.  The script has only been verified to run with Node.js 10 on the MacOS platform.
90*f0df9794SNeil Fuller
91*f0df9794SNeil FullerThe code does query the publicly available Overpass API, but it self-throttles the making of requests to have a minimum of 4 seconds gap between requests.  If the Overpass API throttles the download, then the gap will be increased exponentially.
92*f0df9794SNeil Fuller
93*f0df9794SNeil FullerThe validation and difference analysis can take a really long time to compute. If these tasks are not needed, be sure to add the `--skip_analyze_diffs` and `--skip_validation` flags.
94*f0df9794SNeil Fuller
95*f0df9794SNeil FullerAs of release 2020a, it is possible to run the script with the underlying input data that was used to build the timezone geometries at the time of the release. In the release files, the `input-data.zip` will have all of the necessary input data including the downloaded files from overpass, the `timezones.json` file and the `osmBoundarySources.json` file as well.
96*f0df9794SNeil Fuller
97*f0df9794SNeil Fuller## Limitations of this project
98*f0df9794SNeil Fuller
99*f0df9794SNeil FullerThe data is almost completely comprised of OpenStreetMap data which is editable by anyone.  There are a few guesses on where to draw an arbitrary border in the open waters and a few sparsely inhabited areas.  Some uninhabited islands are omitted from this project.  This project does include timezones in the oceans, but strictly uses territorial waters or Etc/GMT timezones instead of unofficially observed areas such as Exclusive Economic Zones.
100*f0df9794SNeil Fuller
101*f0df9794SNeil Fuller## Contributing
102*f0df9794SNeil Fuller
103*f0df9794SNeil FullerPull requests are welcome!  Please follow the guidelines listed below:
104*f0df9794SNeil Fuller
105*f0df9794SNeil Fuller### Improvements to code
106*f0df9794SNeil Fuller
107*f0df9794SNeil FullerWill be approved subject to code review.
108*f0df9794SNeil Fuller
109*f0df9794SNeil Fuller### Changes to timezone boundary configuration
110*f0df9794SNeil Fuller
111*f0df9794SNeil FullerAny change to the boundary of existing timezones must have some explanation of why the change is necessary.  If there are official, publicly available documents of administrative areas describing their timezone boundary please link to them when making your case.  All changes involving an administrative area changing their observed time should instead be sent to the [timezone database](https://www.iana.org/time-zones).
112*f0df9794SNeil Fuller
113*f0df9794SNeil FullerA linting script will verify the integrity of the `timezones.json`, `osmBoundarySources.json` and `expectedZoneOverlaps.json` files.  The script verifies if all needed overpass sources are properly defined and that there aren't any unneeded overpass downloads.  If an operation to make a timezone boundary requires the use of a manual geometry, a description must be added explaining the operation.  All expected zone overlaps must have a description.
114*f0df9794SNeil Fuller
115*f0df9794SNeil Fuller## Thanks
116*f0df9794SNeil Fuller
117*f0df9794SNeil FullerThanks to following people whose open-source and open-data contributions have made this project possible:
118*f0df9794SNeil Fuller
119*f0df9794SNeil Fuller- All the maintainers of the [timezone database](https://www.iana.org/time-zones).
120*f0df9794SNeil Fuller- Eric Muller for constructing and maintaining the timezone shapefile at [efele.net](http://efele.net/maps/tz/world/).
121*f0df9794SNeil Fuller- The [OpenStreetMap contributor Shinigami](https://www.openstreetmap.org/user/Shinigami) for making lots of edits in OpenStreetMap of various timezone boundaries.
122*f0df9794SNeil Fuller- [Björn Harrtell](https://github.com/bjornharrtell) for all his work and help with [jsts](https://github.com/bjornharrtell/jsts).
123*f0df9794SNeil Fuller
124*f0df9794SNeil Fuller## Licenses
125*f0df9794SNeil Fuller
126*f0df9794SNeil FullerThe code used to construct the timezone boundaries is licensed under the [MIT License](https://opensource.org/licenses/MIT).
127*f0df9794SNeil Fuller
128*f0df9794SNeil FullerThe outputted data is licensed under the [Open Data Commons Open Database License (ODbL)](http://opendatacommons.org/licenses/odbl/).
129