UNPKG

@geonet/geohash

Version:
112 lines (94 loc) 2.61 kB
/** **************************************************************************************************** * File: GeohashStream.js * Project: geohash * @author Nick Soggin <iSkore@users.noreply.github.com> on 11-Feb-2019 *******************************************************************************************************/ 'use strict'; const { Readable } = require( 'stream' ); const getBBoxStartingPoint = require( './getBBoxStartingPoint' ), neighbor = require( './neighbor' ), { isNumber } = require( './utils' ); class GeohashStream extends Readable { /** * GeohashStream * * extends Readable stream * * @param {object} opts - configuration object * @param {number} opts.minLng - bbox min longitude * @param {number} opts.minLat - bbox min latitude * @param {number} opts.maxLng - bbox max longitude * @param {number} opts.maxLat - bbox max latitude * @param {number} opts.precision - geohash precision */ constructor( opts ) { super(); if ( !opts ) { throw new Error( '[GeohashStream] requires options defining bbox (minLng, minLat, maxLng, maxLat) and precision' ); } else if ( !isNumber( opts.minLng ) || !isNumber( opts.minLat ) || !isNumber( opts.maxLng ) || !isNumber( opts.maxLat ) ) { throw new Error( '[GeohashStream] minLng, minLat, maxLng, and maxLat must be numbers' ); } else if ( !isNumber( opts.precision ) ) { throw new Error( '[GeohashStream] precision must be a number' ); } this.startingBBox = getBBoxStartingPoint( opts.minLng, opts.minLat, opts.maxLng, opts.maxLat, opts.precision ); this._x = -1; this._y = -1; this.x = this.startingBBox.lngStep; this.y = this.startingBBox.latStep; this._nextChunk = null; } nextChunk() { if ( this._x === -1 && this._y === -1 ) { this._nextChunk = this.startingBBox.hashSouthWest; this.lastNorth = this._nextChunk; this.lastEast = this._nextChunk; this._x++; this._y++; return this._nextChunk; } else if ( this._x < this.x ) { this._nextChunk = neighbor( this.lastEast, 'e' ); this.lastEast = this._nextChunk; this._x++; return this._nextChunk; } else if ( this._y < this.y ) { this._x = 0; this._nextChunk = neighbor( this.lastNorth, 'n' ); this.lastNorth = this._nextChunk; this.lastEast = this._nextChunk; this._y++; return this._nextChunk; } return null; } _read() { let chunk; while ( ( chunk = this.nextChunk() ) !== null ) { this.push( chunk ); } this.push( null ); } } module.exports = GeohashStream;