Skip to content

Commit

Permalink
Merge pull request #84 from evansiroky/2018g
Browse files Browse the repository at this point in the history
2018g
  • Loading branch information
evansiroky authored Nov 19, 2018
2 parents 05ea092 + d9c10cc commit fc6f1be
Show file tree
Hide file tree
Showing 9 changed files with 237 additions and 154 deletions.
10 changes: 5 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,30 @@ sudo: false
language: node_js

node_js:
- "10"
- "9"
- "8"
- "7"
- "6"
- "5"
- "4"

env:
- COVERAGE=false

matrix:
fast_finish: true
include:
- node_js: "4"
- node_js: "6"
env: COVERAGE=true
script: "npm run codeclimate"
allow_failures:
- node_js: "4"
- node_js: "6"
env: COVERAGE=true
script: "npm run codeclimate"

before_script:
- npm prune
after_success:
- npm run semantic-release
- travis-deploy-once "npm run semantic-release"
branches:
except:
- /^v\d+\.\d+\.\d+$/
18 changes: 13 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,29 @@ The most up-to-date and accurate node.js geographical timezone lookup package.

## Usage

```javascript
var geoTz = require('geo-tz')

geoTz(47.650499, -122.350070) // 'America/Los_Angeles'
geoTz.preCache() // optionally load all features into memory
geoTz(47.650499, -122.350070) // ['America/Los_Angeles']
geoTz(43.839319, 87.526148) // ['Asia/Shanghai', 'Asia/Urumqi']
```

## API Docs:

As of Version 4, there is now only one API call and no dependency on moment-timezone.
As of Version 5, the API now returns a list of possible timezones as there are certain coordinates where the timekeeping method will depend on the person you ask.

### geoTz(lat, lon)

Returns the timezone name found at `lat`, `lon`. The timezone name will be a timezone identifier as defined in the [timezone database](https://www.iana.org/time-zones). The underlying geographic data is obtained from the [timezone-boudary-builder](https://github.com/evansiroky/timezone-boundary-builder) project.
Returns the timezone names found at `lat`, `lon`. The timezone names will be the timezone identifiers as defined in the [timezone database](https://www.iana.org/time-zones). The underlying geographic data is obtained from the [timezone-boudary-builder](https://github.com/evansiroky/timezone-boundary-builder) project.

This library does an exact geographic lookup which has tradeoffs. It is perhaps a little bit slower that other libraries, has a large installation size on disk and cannot be used in the browser. However, the results are more accurate than other libraries that compromise by approximating the lookup of the data.
This library does an exact geographic lookup which has tradeoffs. It is perhaps a little bit slower that other libraries, has a larger installation size on disk and cannot be used in the browser. However, the results are more accurate than other libraries that compromise by approximating the lookup of the data.

The data is indexed for fast analysis with automatic caching (with time expiration) of subregions of geographic data for when a precise lookup is needed.
The data is indexed for fast analysis with automatic caching with time expiration (or optional an unexpiring cache of the whole world) of subregions of geographic data for when a precise lookup is needed.

### geoTz.preCache()

Loads all geographic features into memory in an unexpiring cache. This has tradeoffs. More memory will be consumed and it will take a little longer before the program is ready to start looking up features, but future lookups will be a lot faster - especially for areas which haven't had a lookup in a while.

## An Important Note About Maintenance

Expand Down
Binary file modified data.zip
Binary file not shown.
52 changes: 42 additions & 10 deletions lib/find.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,48 @@
var fs = require('fs')
var path = require('path')

var geobuf = require('geobuf')
var inside = require('@turf/boolean-point-in-polygon').default
var Cache = require( "timed-cache" )
var Cache = require('timed-cache')
var Pbf = require('pbf')
var point = require('@turf/helpers').point

var tzData = require('../data/index.json')

const featureCache = new Cache()
let featureCache = new Cache()

var loadFeatures = function(quadPos) {
/**
* A function that will load all features into an unexpiring cache
*/
var preCache = function () {
const _eternalCache = {}
featureCache = {
get: (quadPos) => _eternalCache[quadPos]
}

// shoutout to github user @magwo for an initial version of this recursive function
var preloadFeaturesRecursive = function (curTzData, quadPos) {
if (curTzData === 'f') {
var geoJson = loadFeatures(quadPos)
_eternalCache[quadPos] = geoJson
} else if (typeof curTzData === 'object') {
Object.getOwnPropertyNames(curTzData).forEach(function (value) {
preloadFeaturesRecursive(curTzData[value], quadPos + value)
})
}
}
preloadFeaturesRecursive(tzData.lookup, '')
}

var loadFeatures = function (quadPos) {
// exact boundaries saved in file
// parse geojson for exact boundaries
var filepath = quadPos.split('').join('/')
var data = new Pbf(fs.readFileSync(__dirname + '/../data/' + filepath + '/geo.buf'))
var data = new Pbf(fs.readFileSync(
path.join(__dirname, '/../data/', filepath, '/geo.buf'))
)
var geoJson = geobuf.decode(data)
return geoJson;
return geoJson
}

const oceanZones = [
Expand Down Expand Up @@ -137,17 +163,22 @@ var getTimezone = function (lat, lon) {
featureCache.put(quadPos, geoJson)
}

var timezonesContainingPoint = []

for (var i = 0; i < geoJson.features.length; i++) {
if (inside(pt, geoJson.features[i])) {
return geoJson.features[i].properties.tzid
timezonesContainingPoint.push(geoJson.features[i].properties.tzid)
}
}

// not within subarea, therefore must be timezone at sea
return getTimezoneAtSea(lon)
} else if (typeof curTzData === 'number') {
// if at least one timezone contained the point, return those timezones,
// otherwise must be timezone at sea
return timezonesContainingPoint.length > 0
? timezonesContainingPoint
: getTimezoneAtSea(lon)
} else if (curTzData.length > 0) {
// exact match found
return tzData.timezones[curTzData]
return curTzData.map(idx => tzData.timezones[idx])
} else if (typeof curTzData !== 'object') {
// not another nested quad index, throw error
err = new Error('Unexpected data type')
Expand All @@ -161,3 +192,4 @@ var getTimezone = function (lat, lon) {
}

module.exports = getTimezone
module.exports.preCache = preCache
Loading

0 comments on commit fc6f1be

Please sign in to comment.