Code Monkey home page Code Monkey logo

node-osm-stream's Introduction

node-osm-stream

Overview

A fast and flexible NodeJS-based streaming parser for OpenStreetMap (.osm) files.

  • Both incoming and outgoing streams available for piping from/to other streams
  • Able to deal with large .osm files easily without loading the whole file onto memory
  • Provided with the flexibility to work with and modify OSM objects (nodes, ways, relations) easily as it streams to you

Powered by node-expat for blazing fast parsing.

Table of Content


Quick Start

Install

npm install node-osm-stream

No fuss, no lints

Example: Reading from a local .osm file

var fs = require('fs');
var OSMStream = require('node-osm-stream');
var parser = OSMStream();

// open a local .osm filestream
fs.createReadStream('./path/to/file.osm')
	.pipe(parser);

parser.on('node', function(node, callback){
	// Modify current node object as you wish
	// and pass it back to the callback.
	// Or pass 'null' or 'false' to prevent the object being 
	// written to outgoing stream
	console.log(node);
	callback(node);
});

parser.on('way', function(way, callback){ callback(way); });

parser.on('relation', function(way, callback){ callback(relation); });

Easy-peasy, lemon-squeezy.

More examples

More advanced examples are available in the ./examples folder

Stream and format outgoing data to console (process.stdout)

Source: /examples/stream-to-stdout.js

To run example:

node ./examples/stream-to-stdout.js

Writing to a JSON file using Writeable steam (fs.createWriteStream)

Source: /examples/write-to-json.js

To run example:

node ./examples/write-to-json.js

API

Class: OSMStream

Class inherited from stream.Transform

Methods

All methods are inherited from stream.Transform

Events

Events: 'node', 'way', 'relation'

When an object (node/way/relation) from the .osm file has been parsed fully with its attributes and children (if any) ready, it will emit a 'node' or 'way' or 'relation' event, depending on the object type.

You can modify the outgoing data and passing it back to the callback. Or you can prevent the data from being passed downstream by passing back a null or false

It's important to note that since this is a streaming parser, any other objects (ways/relations) that may have referenced a skipped node may still hold its reference. It is up to the implementation to remove its references.

To see an example of a possible implementation, take a look at /examples/write-to-json.js

Note: If this event was registered, the callback must be passed back.

parser.on('node', function(node, callback) {
  // modify the node object as necessary and pass back to callback
  // or send a null or false to prevent it from going downstream
  callback(node);
});

parser.on('way', function(way, callback) {
  ...
  callback(way);
});
parser.on('relation', function(relation, callback) {
  ...
  callback(relation);
});

Event: 'writeable'

When a chunk of data is ready to be written to the outgoing stream, it will emit a 'writeable' event.

You can modify the outgoing data and passing it back to the callback. Or you can prevent the data from being passed downstream by passing back a null or false

Note: If this event was registered, the callback must be passed back.

parser.on('writeable', function(data, callback) {
  // there is some data to be passed to outgoing stream
  // modify 'data' as needed
  callback(data);
});

Event: 'flush'

After all the written data has been consumed through the outgoing stream, it will emit a 'flush' event. This will happened before the 'end' event is sent to signal the end of the readable side.

You can choose to pass in as much data as needed by passing it through the callback. Any data passed back will be written to the outgoing stream before the 'end' event is emitted.

Note: If this event was registered, the callback must be passed back.

parser.on('flush', function(callback) {
  var last_data = 'This is the last string sent to the outgoing stream';
  callback(last_data);
});

Events inherited from stream.Transform

In addition to the events above, the following are events inherited from stream.Transform class. Please refer to the offical documentation for more info: NodeJS API Documentation: stream.Transform

  • Event: 'readable'
  • Event: 'data'
  • Event: 'end'
  • Event: 'close'
  • Event: 'error'
  • Event: 'drain'
  • Event: 'finish'
  • Event: 'pipe'
  • Event: 'unpipe'

Test

npm test

Known Issues

Credits

Links

License

Copyright (c) 2014 Hafiz Ismail. This software is licensed under the MIT License.

node-osm-stream's People

Contributors

sogko avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

nvdnkpr sharpchi

node-osm-stream's Issues

Out of memory error

I'm tryed to process large .osm file and got this:

<--- Last few GCs --->
[4314:0x3be41c0]   788839 ms: Mark-sweep 1349.7 (1406.1) -> 1349.5 (1406.6) MB, 1499.5 / 0.0 ms  allocation failure GC in old space requested
[4314:0x3be41c0]   790368 ms: Mark-sweep 1349.5 (1406.6) -> 1349.4 (1375.1) MB, 1529.3 / 0.0 ms  last resort GC in old space requested
[4314:0x3be41c0]   791849 ms: Mark-sweep 1349.4 (1375.1) -> 1349.4 (1374.6) MB, 1480.8 / 0.0 ms  last resort GC in old space requested

<--- JS stacktrace --->
==== JS stack trace =========================================
    0: ExitFrame [pc: 0x13944e60427d]
Security context: 0x1039978206a9 <JSObject>
    1: fileProcessor [/importer.js:~23] [pc=0x13944ea5b32c](this=0xc5ce40abbe9 <OSMStream map = 0x184279b53d81>,data=0x3b63b47298e9 <Object map = 0x184279b38da1>,callback=0x3b63b4729a79 <JSBoundFunction (BoundTargetFunction 0x3b63b4729a39)>)
    2: pushData [/node_modules/node-osm-stream/lib/node-osm-stream.js:~43] [pc=0x1...
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
 1: node::Abort() [/usr/local/bin/node]
 2: 0x88050c [/usr/local/bin/node]
 3: v8::Utils::ReportOOMFailure(char const*, bool) [/usr/local/bin/node]
 4: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [/usr/local/bin/node]
 5: v8::internal::Factory::NewFixedArrayWithMap(v8::internal::Heap::RootListIndex, int, v8::internal::PretenureFlag) [/usr/local/bin/node]
 6: v8::internal::HashTable<v8::internal::NameDictionary, v8::internal::NameDictionaryShape>::New(v8::internal::Isolate*, int, v8::internal::PretenureFlag, v8::internal::MinimumCapacity) [/usr/local/bin/node]
 7: v8::internal::HashTable<v8::internal::NameDictionary, v8::internal::NameDictionaryShape>::EnsureCapacity(v8::internal::Handle<v8::internal::NameDictionary>, int, v8::internal::PretenureFlag) [/usr/local/bin/node]
 8: v8::internal::BaseNameDictionary<v8::internal::NameDictionary, v8::internal::NameDictionaryShape>::EnsureCapacity(v8::internal::Handle<v8::internal::NameDictionary>, int) [/usr/local/bin/node]
 9: v8::internal::BaseNameDictionary<v8::internal::NameDictionary, v8::internal::NameDictionaryShape>::AddNoUpdateNextEnumerationIndex(v8::internal::Handle<v8::internal::NameDictionary>, v8::internal::Handle<v8::internal::Name>, v8::internal::Handle<v8::internal::Object>, v8::internal::PropertyDetails, int*) [/usr/local/bin/node]
10: v8::internal::BaseNameDictionary<v8::internal::NameDictionary, v8::internal::NameDictionaryShape>::Add(v8::internal::Handle<v8::internal::NameDictionary>, v8::internal::Handle<v8::internal::Name>, v8::internal::Handle<v8::internal::Object>, v8::internal::PropertyDetails, int*) [/usr/local/bin/node]
11: v8::internal::LookupIterator::ApplyTransitionToDataProperty(v8::internal::Handle<v8::internal::JSReceiver>) [/usr/local/bin/node]
12: v8::internal::Object::AddDataProperty(v8::internal::LookupIterator*, v8::internal::Handle<v8::internal::Object>, v8::internal::PropertyAttributes, v8::internal::ShouldThrow, v8::internal::Object::StoreFromKeyed) [/usr/local/bin/node]
 13: v8::internal::Object::SetProperty(v8::internal::LookupIterator*, v8::internal::Handle<v8::internal::Object>, v8::internal::LanguageMode, v8::internal::Object::StoreFromKeyed) [/usr/local/bin/node]
 14: v8::internal::Runtime::SetObjectProperty(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, v8::internal::LanguageMode) [/usr/local/bin/node]
 15: v8::internal::Runtime_SetProperty(int, v8::internal::Object**, v8::internal::Isolate*) [/usr/local/bin/node]
 16: 0x13944e60427d

node -v

v10.2.1

Error when passing in 'null' / 'false' to 'flush' event callback

Error when passing in 'null' / 'false' to 'flush' event callback.

Trace:

TypeError: First argument needs to be a number, array or string.
    at new Buffer (buffer.js:188:15)
    at OSMStream.onFlush (/Users/hafiz/dev/routine/datasets/osm-arangoimp-export/node_modules/node-osm-stream/lib/node-osm-stream.js:93:19)
    at OSMArangoImpExport.<anonymous> (/Users/hafiz/dev/routine/datasets/osm-arangoimp-export/lib/node-osm-arangoimp-export.js:68:5)
    at OSMStream.EventEmitter.emit (events.js:95:17)
    at OSMStream._flush (/Users/hafiz/dev/routine/datasets/osm-arangoimp-export/node_modules/node-osm-stream/lib/node-osm-stream.js:92:10)
    at OSMStream.<anonymous> (_stream_transform.js:130:12)
    at OSMStream.g (events.js:180:16)
    at OSMStream.EventEmitter.emit (events.js:117:20)
    at finishMaybe (_stream_writable.js:360:12)
    at endWritable (_stream_writable.js:367:3)

Current workaround: pass back an empty string.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.