aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorevansiroky <evan.siroky@yahoo.com>2018-04-03 14:10:42 -0700
committerevansiroky <evan.siroky@yahoo.com>2018-04-03 14:10:42 -0700
commit263258400940da754e363cbeca70bda1394462f7 (patch)
treebf5775df482001b1e5a46554a666b7cf08e03c5d
parenta4ae383f3ddddaf6d433d60698d1bc1502994f82 (diff)
downloadtimezone-boundary-builder-263258400940da754e363cbeca70bda1394462f7.tar.gz
Add timezones in oceans and prepare for 2018d release
-rw-r--r--2017c.pngbin309391 -> 0 bytes
-rw-r--r--2018d.pngbin0 -> 383041 bytes
-rw-r--r--CHANGELOG.md10
-rw-r--r--README.md6
-rw-r--r--index.js128
5 files changed, 126 insertions, 18 deletions
diff --git a/2017c.png b/2017c.png
deleted file mode 100644
index b125ccb..0000000
--- a/2017c.png
+++ /dev/null
Binary files differ
diff --git a/2018d.png b/2018d.png
new file mode 100644
index 0000000..0cd2375
--- /dev/null
+++ b/2018d.png
Binary files differ
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
diff --git a/README.md b/README.md
index aa168e3..c1e82f3 100644
--- a/README.md
+++ b/README.md
@@ -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
diff --git a/index.js b/index.js
index 2192e11..e471aa1 100644
--- a/index.js
+++ b/index.js
@@ -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')