UNPKG

verrazzano

Version:

Streaming geospatial format conversion

91 lines (64 loc) 3.01 kB
"use strict"; exports.__esModule = true; exports.default = void 0; var _from = _interopRequireDefault(require("from2")); var _gdalAsync = _interopRequireDefault(require("gdal-async")); var _lodash = _interopRequireDefault(require("lodash.mapvalues")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const wgs84 = _gdalAsync.default.SpatialReference.fromProj4('+init=epsg:4326'); const isGDALDate = v => v && typeof v === 'object' && v.year != null && v.month != null && v.day != null; // https://github.com/OSGeo/gdal/blob/e3a2bc5c3c474ca31c13950ac6d2555a2d9389c5/gdal/ogr/ogrsf_frmts/gtm/gtmwaypointlayer.cpp#L158 // These date objects are really strange and non-standard const parseGDALDate = time => { const utcTime = Date.UTC(time.year || 0, time.month - 1 || 0, time.day || 0, time.hour || 0, time.minute || 0, time.second || 0); if (!time.timezone || time.timezone === 1) return new Date(utcTime).toISOString(); const offset = (time.timezone - 100) * 15; return new Date(utcTime - offset).toISOString(); }; const fixDates = v => isGDALDate(v) ? parseGDALDate(v) : v; // GDAL File -> GeoJSON Features // Inspired by shp2json var _default = path => { const file = _gdalAsync.default.open(path); const layerCount = file.layers.count(); let nextLayer = 0; let currentLayer, currentTransformation; const getNextLayer = () => { currentLayer = file.layers.get(nextLayer++); currentTransformation = new _gdalAsync.default.CoordinateTransformation(currentLayer.srs || wgs84, wgs84); }; getNextLayer(); return _from.default.obj(function (size, next) { let pushed = 0; const writeFeature = () => { const isLastLayer = nextLayer === layerCount; // grab the feature we're working with let feature = currentLayer.features.next(); if (!feature) { if (isLastLayer) { // we hit the end of the final layer, finish this.push(null); return; } // we hit the end of the layer, go to the next layer and continue getNextLayer(); feature = currentLayer.features.next(); } // get the geometry and project the coordinates let geometry; try { geometry = feature.getGeometry(); if (geometry) geometry.transform(currentTransformation); } catch (e) { return process.nextTick(writeFeature); // go to next feature in layer } const featureObject = { type: 'Feature', properties: (0, _lodash.default)(feature.fields.toObject(), fixDates), geometry: geometry ? geometry.toObject() : undefined }; ++pushed; this.push(featureObject); if (pushed >= size) return next(null); // no more space available to write, write what we have and wait process.nextTick(writeFeature); // more space available to write, go to next feature in layer }; writeFeature(); }); }; exports.default = _default; module.exports = exports.default;