diff options
author | evansiroky <evan.siroky@yahoo.com> | 2018-04-03 14:10:42 -0700 |
---|---|---|
committer | evansiroky <evan.siroky@yahoo.com> | 2018-04-03 14:10:42 -0700 |
commit | 263258400940da754e363cbeca70bda1394462f7 (patch) | |
tree | bf5775df482001b1e5a46554a666b7cf08e03c5d | |
parent | a4ae383f3ddddaf6d433d60698d1bc1502994f82 (diff) | |
download | timezone-boundary-builder-263258400940da754e363cbeca70bda1394462f7.tar.gz |
Add timezones in oceans and prepare for 2018d release
-rw-r--r-- | 2017c.png | bin | 309391 -> 0 bytes | |||
-rw-r--r-- | 2018d.png | bin | 0 -> 383041 bytes | |||
-rw-r--r-- | CHANGELOG.md | 10 | ||||
-rw-r--r-- | README.md | 6 | ||||
-rw-r--r-- | index.js | 128 |
5 files changed, 126 insertions, 18 deletions
diff --git a/2017c.png b/2017c.png Binary files differdeleted file mode 100644 index b125ccb..0000000 --- a/2017c.png +++ /dev/null diff --git a/2018d.png b/2018d.png Binary files differnew file mode 100644 index 0000000..0cd2375 --- /dev/null +++ b/2018d.png diff --git a/CHANGELOG.md b/CHANGELOG.md index 622745e..983f39e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,10 @@ -## Unreleased +## 2018d + +### Zone Changes + +* Add timezones in the oceans ([#34](https://github.com/evansiroky/timezone-boundary-builder/issues/34)) + * Shapefiles and geojson are now outputted as with or without oceans +* Update to latest OSM data ### Other Changes @@ -8,7 +14,7 @@ * Save validation overlaps to file. * Add links to troubleshooting wiki for common errors. * Update README - * Add list of geogrphical lookup libraries + * Add list of geographical lookup libraries * Add troubleshooting wiki ## 2017c @@ -2,11 +2,11 @@ The goal of this project is to produce a shapefile with the boundaries of the world's timezones using OpenStreetMap data. -<p align="center"><img src="2017c.png" /></p> +<p align="center"><img src="2018d.png" /></p> ## Shapefiles and data -The shapefiles are available for download in this project's [releases](https://github.com/evansiroky/timezone-boundary-builder/releases). 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`). +The 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`). This 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. @@ -52,7 +52,7 @@ The code does query the publicly available overpass API, but it self-throttles t ## Limitations of this project -The data is almost completely comprised of OpenStreetMap data which is editable by anyone. There are a few educated 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. All of Antarctica is currently omitted as well. This project also doesn't include any timezones in oceans except where the territorial waters of a country would apply. +The 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. All of Antarctica is currently omitted and instead shows up as a Etc/GMT timezone as if it were the ocean. ## Contributing @@ -283,9 +283,10 @@ var getDataSource = function (source) { * - reduce geometry precision * * @param {Geometry} geom The jsts geometry of the timezone - * @return {String} Stringified geojson + * @param {boolean} returnAsObject if true, return as object, otherwise return stringified + * @return {Object|String} geojson as object or stringified */ -var postProcessZone = function (geom) { +var postProcessZone = function (geom, returnAsObject) { // reduce precision of geometry const geojson = geomToGeoJson(precisionReducer.reduce(geom)) @@ -335,7 +336,7 @@ var postProcessZone = function (geom) { newGeojson.coordinates = filteredPolygons } - return JSON.stringify(newGeojson) + return returnAsObject ? newGeojson : JSON.stringify(newGeojson) } var makeTimezoneBoundary = function (tzid, callback) { @@ -387,7 +388,7 @@ var getDistZoneGeom = function (tzid) { } var validateTimezoneBoundaries = function () { - console.log('do validation') + console.log('do validation... this may take a few minutes') var allZonesOk = true var zones = Object.keys(zoneCfg) var compareTzid, tzid, zoneGeom @@ -429,24 +430,105 @@ var validateTimezoneBoundaries = function () { return allZonesOk ? null : 'Zone validation unsuccessful' } +let oceanZoneBoundaries + +var addOceans = function (callback) { + console.log('adding ocean boundaries') + const oceanZones = [ + { tzid: 'Etc/GMT-12', left: 172.5, right: 180 }, + { tzid: 'Etc/GMT-11', left: 157.5, right: 172.5 }, + { tzid: 'Etc/GMT-10', left: 142.5, right: 157.5 }, + { tzid: 'Etc/GMT-9', left: 127.5, right: 142.5 }, + { tzid: 'Etc/GMT-8', left: 112.5, right: 127.5 }, + { tzid: 'Etc/GMT-7', left: 97.5, right: 112.5 }, + { tzid: 'Etc/GMT-6', left: 82.5, right: 97.5 }, + { tzid: 'Etc/GMT-5', left: 67.5, right: 82.5 }, + { tzid: 'Etc/GMT-4', left: 52.5, right: 67.5 }, + { tzid: 'Etc/GMT-3', left: 37.5, right: 52.5 }, + { tzid: 'Etc/GMT-2', left: 22.5, right: 37.5 }, + { tzid: 'Etc/GMT-1', left: 7.5, right: 22.5 }, + { tzid: 'Etc/GMT', left: -7.5, right: 7.5 }, + { tzid: 'Etc/GMT+1', left: -22.5, right: -7.5 }, + { tzid: 'Etc/GMT+2', left: -37.5, right: -22.5 }, + { tzid: 'Etc/GMT+3', left: -52.5, right: -37.5 }, + { tzid: 'Etc/GMT+4', left: -67.5, right: -52.5 }, + { tzid: 'Etc/GMT+5', left: -82.5, right: -67.5 }, + { tzid: 'Etc/GMT+6', left: -97.5, right: -82.5 }, + { tzid: 'Etc/GMT+7', left: -112.5, right: -97.5 }, + { tzid: 'Etc/GMT+8', left: -127.5, right: -112.5 }, + { tzid: 'Etc/GMT+9', left: -142.5, right: -127.5 }, + { tzid: 'Etc/GMT+10', left: -157.5, right: -142.5 }, + { tzid: 'Etc/GMT+11', left: -172.5, right: -157.5 }, + { tzid: 'Etc/GMT+12', left: -180, right: -172.5 } + ] + + const zones = Object.keys(zoneCfg) + + oceanZoneBoundaries = oceanZones.map(zone => { + console.log(zone.tzid) + const geoJson = polygon([[ + [zone.left, 90], + [zone.left,-90], + [zone.right,-90], + [zone.right,90], + [zone.left, 90] + ]]).geometry + + let geom = geoJsonToGeom(geoJson) + + // diff against every zone + zones.forEach(distZone => { + geom = debugGeo('diff', geom, getDistZoneGeom(distZone)) + }) + + return { + geom: postProcessZone(geom, true), + tzid: zone.tzid + } + }) + + callback() +} + var combineAndWriteZones = function (callback) { var stream = fs.createWriteStream('./dist/combined.json') + var streamWithOceans = fs.createWriteStream('./dist/combined-with-oceans.json') var zones = Object.keys(zoneCfg) stream.write('{"type":"FeatureCollection","features":[') + streamWithOceans.write('{"type":"FeatureCollection","features":[') for (var i = 0; i < zones.length; i++) { if (i > 0) { stream.write(',') + streamWithOceans.write(',') } var feature = { type: 'Feature', properties: { tzid: zones[i] }, geometry: geomToGeoJson(getDistZoneGeom(zones[i])) } - stream.write(JSON.stringify(feature)) + const stringified = JSON.stringify(feature) + stream.write(stringified) + streamWithOceans.write(stringified) } - stream.end(']}', callback) + oceanZoneBoundaries.forEach(boundary => { + streamWithOceans.write(',') + var feature = { + type: 'Feature', + properties: { tzid: boundary.tzid }, + geometry: boundary.geom + } + streamWithOceans.write(JSON.stringify(feature)) + }) + asynclib.parallel([ + cb => { + stream.end(']}', cb) + }, + cb => { + streamWithOceans.end(']}', cb) + } + ], callback) } asynclib.auto({ @@ -476,7 +558,10 @@ asynclib.auto({ cb(validateTimezoneBoundaries()) } }], - mergeZones: ['validateZones', function (results, cb) { + addOceans: ['validateZones', function (results, cb) { + addOceans(cb) + }], + mergeZones: ['addOceans', function (results, cb) { console.log('merge zones') combineAndWriteZones(cb) }], @@ -484,14 +569,31 @@ asynclib.auto({ console.log('zip geojson') exec('zip dist/timezones.geojson.zip dist/combined.json', cb) }], + zipGeoJsonWithOceans: ['mergeZones', function (results, cb) { + console.log('zip geojson with oceans') + exec('zip dist/timezones-with-oceans.geojson.zip dist/combined-with-oceans.json', cb) + }], makeShapefile: ['mergeZones', function (results, cb) { console.log('convert from geojson to shapefile') - rimraf.sync('dist/dist') - rimraf.sync('dist/combined_shapefile.*') - exec('ogr2ogr -nlt MULTIPOLYGON dist/combined_shapefile.shp dist/combined.json OGRGeoJSON', function (err, stdout, stderr) { - if (err) { return cb(err) } - exec('zip dist/timezones.shapefile.zip dist/combined_shapefile.*', cb) - }) + rimraf.sync('dist/combined-shapefile.*') + exec( + 'ogr2ogr -nlt MULTIPOLYGON dist/combined-shapefile.shp dist/combined.json OGRGeoJSON', + function (err, stdout, stderr) { + if (err) { return cb(err) } + exec('zip dist/timezones.shapefile.zip dist/combined-shapefile.*', cb) + } + ) + }], + makeShapefileWithOceans: ['mergeZones', function (results, cb) { + console.log('convert from geojson with oceans to shapefile') + rimraf.sync('dist/combined-shapefile-with-oceans.*') + exec( + 'ogr2ogr -nlt MULTIPOLYGON dist/combined-shapefile-with-oceans.shp dist/combined-with-oceans.json OGRGeoJSON', + function (err, stdout, stderr) { + if (err) { return cb(err) } + exec('zip dist/timezones-with-oceans.shapefile.zip dist/combined-shapefile-with-oceans.*', cb) + } + ) }] }, function (err, results) { console.log('done') |