This is an automated email from the git hooks/post-receive script. sebastic pushed a commit to branch master in repository node-osmium.
commit 9a9a819fc63ceb7e7b8358d21c2199c4e0d34ad6 Author: Bas Couwenberg <sebas...@xs4all.nl> Date: Fri Mar 6 15:16:35 2015 +0100 Imported Upstream version 0.1.2 --- .gitignore | 2 +- .travis.yml | 13 +-- CHANGELOG.md | 7 ++ Makefile | 17 ++-- binding.gyp | 1 + common.gypi | 1 + lib/osmium.js | 6 +- package.json | 11 ++- src/buffer.hpp | 88 ------------------- src/file_wrap.cpp | 11 +-- src/file_wrap.hpp | 20 ++--- src/handler.cpp | 191 +++++++++++++++++++++++++++++++++++++++++- src/handler.hpp | 54 ++++++------ src/location_handler_wrap.cpp | 38 +++++++++ src/location_handler_wrap.hpp | 75 +++++++++++++++++ src/node_osmium.cpp | 4 +- src/osm_node_wrap.cpp | 41 +++++---- src/osm_node_wrap.hpp | 13 ++- src/osm_object_wrap.cpp | 35 ++++++++ src/osm_object_wrap.hpp | 21 ++++- src/osm_relation_wrap.cpp | 20 ++--- src/osm_relation_wrap.hpp | 11 +-- src/osm_way_wrap.cpp | 26 +++--- src/osm_way_wrap.hpp | 11 +-- src/reader_wrap.cpp | 170 ++++++++++++++++++++++++++----------- src/reader_wrap.hpp | 38 ++++----- test/osmium.test.js | 104 ++++++++++++++++++----- 27 files changed, 714 insertions(+), 315 deletions(-) diff --git a/.gitignore b/.gitignore index 31fef51..b13eb67 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ node_modules -lib/osmium.node +lib/binding .DS_Store build berlin-latest.osm.pbf diff --git a/.travis.yml b/.travis.yml index 0f23dda..eb695f4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,16 +4,19 @@ node_js: - "0.10" before_install: + # we need c++11 compatible g++ + - sudo apt-add-repository --yes ppa:ubuntu-toolchain-r/test + - sudo apt-get -y update + - sudo apt-get -y install gcc-4.7 g++-4.7 # first test install of binary - - npm install --verbose - - make test +# - npm install --verbose +# - make test install: # next test source compile, so get dependencies - sudo apt-add-repository --yes ppa:mapnik/boost - - sudo apt-add-repository --yes ppa:ubuntu-toolchain-r/test - sudo apt-get -y update -qq - - sudo apt-get -y install git gcc-4.7 g++-4.7 build-essential libboost-dev zlib1g-dev protobuf-compiler libprotobuf-lite7 libprotobuf-dev libexpat1-dev libsparsehash-dev + - sudo apt-get -y install git build-essential libboost-dev zlib1g-dev protobuf-compiler libprotobuf-lite7 libprotobuf-dev libexpat1-dev libsparsehash-dev - git clone https://github.com/scrosby/OSM-binary.git - cd OSM-binary/src - make && sudo make install @@ -21,7 +24,7 @@ install: before_script: - git clone https://github.com/osmcode/libosmium.git ../libosmium - - CXX=g++-4.7 npm install + - CXX=g++-4.7 npm install --build-from-source script: - make test diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..c320724 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,7 @@ +## Changelog + +### 0.1.2 + + - Upgraded node-pre-gyp to 0.5.10 + + diff --git a/Makefile b/Makefile index bca59f3..645cb37 100755 --- a/Makefile +++ b/Makefile @@ -1,10 +1,13 @@ all: osmium.node -./build: - `npm explore npm -g -- pwd`/bin/node-gyp-bin/node-gyp configure +./node_modules/.bin/node-gyp: + npm install node-gyp -osmium.node: binding.gyp Makefile ./build - `npm explore npm -g -- pwd`/bin/node-gyp-bin/node-gyp --verbose build +./build: binding.gyp ./node_modules/.bin/node-gyp + ./node_modules/.bin/node-gyp configure + +osmium.node: Makefile ./build + ./node_modules/.bin/node-gyp build clean: rm -rf ./build @@ -14,11 +17,7 @@ rebuild: @make clean @make -test/data/berlin-latest.osm.pbf: - cd test/data; \ - wget http://download.geofabrik.de/europe/germany/berlin-latest.osm.pbf - -test: test/data/berlin-latest.osm.pbf +test: @PATH="./node_modules/mocha/bin:${PATH}" && NODE_PATH="./lib:$(NODE_PATH)" mocha -R spec --timeout 10000 indent: diff --git a/binding.gyp b/binding.gyp index e262a27..740c262 100644 --- a/binding.gyp +++ b/binding.gyp @@ -10,6 +10,7 @@ "sources": [ "src/node_osmium.cpp", "src/handler.cpp", + "src/location_handler_wrap.cpp", "src/file_wrap.cpp", "src/reader_wrap.cpp", "src/osm_object_wrap.cpp", diff --git a/common.gypi b/common.gypi index f59efdf..3e0d5de 100644 --- a/common.gypi +++ b/common.gypi @@ -13,6 +13,7 @@ 'Release': { 'xcode_settings': { 'GCC_OPTIMIZATION_LEVEL': 's', + 'OTHER_CPLUSPLUSFLAGS':['-gline-tables-only','-fno-omit-frame-pointer'], }, 'ldflags': [ '-Wl,-s' diff --git a/lib/osmium.js b/lib/osmium.js index ccbb5cd..1722bfb 100644 --- a/lib/osmium.js +++ b/lib/osmium.js @@ -1,3 +1,7 @@ -var osmium = require('./osmium.node'); +var osmium = require('./binding/osmium.node'); exports = module.exports = osmium; exports.version = require('../package').version; + +exports.Node.prototype.date = function() { + return new Date(1000*this.timestamp); +} \ No newline at end of file diff --git a/package.json b/package.json index f2cd1de..d9509ba 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "contributors": [ "Jochen Topf <joto>" ], - "version": "0.1.1", + "version": "0.1.2", "main": "./lib/osmium.js", "bugs": { "email": "d...@mapbox.com", @@ -25,12 +25,11 @@ }, "binary": { "module_name": "osmium", - "module_path": "./lib", - "remote_uri": "http://node-osmium.s3.amazonaws.com", - "template": "{module_name}-v{major}.{minor}.{patch}-{node_abi}-{platform}-{arch}.tar.gz" + "module_path": "./lib/binding/", + "host": "https://node-osmium.s3.amazonaws.com" }, "dependencies": { - "node-pre-gyp": "~0.1.4" + "node-pre-gyp": "~0.5.10" }, "bundledDependencies":["node-pre-gyp"], "devDependencies": { @@ -41,7 +40,7 @@ "node": ">= 0.6.13 < 0.11.0" }, "scripts": { - "install": "node-pre-gyp rebuild", + "install": "node-pre-gyp install --fallback-to-build", "test": "mocha -R spec" } } diff --git a/src/buffer.hpp b/src/buffer.hpp deleted file mode 100644 index ccb28a1..0000000 --- a/src/buffer.hpp +++ /dev/null @@ -1,88 +0,0 @@ -// c++11 -#include <sstream> - -// v8 -#include <v8.h> - -// node.js -#include <node.h> -#include <node_version.h> -#include <node_object_wrap.h> - -// osmium -#include <osmium/memory/buffer.hpp> -#include <osmium/osm/dump.hpp> -#include <osmium/visitor.hpp> - -using namespace v8; - -namespace node_osmium { - - class Buffer : public node::ObjectWrap { - - public: - - static Persistent<FunctionTemplate> constructor; - static void Initialize(Handle<Object> target); - static Handle<Value> New(const Arguments& args); - static Handle<Value> dump(const Arguments& args); - Buffer(reader_ptr reader); - void _ref() { - Ref(); - } - void _unref() { - Unref(); - } - osmium::memory::Buffer buf; - - private: - - ~Buffer(); - }; - - Persistent<FunctionTemplate> Buffer::constructor; - - void Buffer::Initialize(Handle<Object> target) { - HandleScope scope; - constructor = Persistent<FunctionTemplate>::New(FunctionTemplate::New(Buffer::New)); - constructor->InstanceTemplate()->SetInternalFieldCount(1); - constructor->SetClassName(String::NewSymbol("Buffer")); - NODE_SET_PROTOTYPE_METHOD(constructor, "dump", dump); - target->Set(String::NewSymbol("Buffer"), constructor->GetFunction()); - } - - Buffer::Buffer(reader_ptr reader) : - ObjectWrap(), - buf(reader.get()->read()) { - } - - Buffer::~Buffer() { - } - - Handle<Value> Buffer::New(const Arguments& args) { - HandleScope scope; - if (args[0]->IsExternal()) { - Local<External> ext = Local<External>::Cast(args[0]); - void* ptr = ext->Value(); - Buffer* b = static_cast<Buffer*>(ptr); - b->Wrap(args.This()); - return args.This(); - } else { - return ThrowException(Exception::TypeError(String::New("osmium.Buffer cannot be created in Javascript"))); - } - return Undefined(); - } - - - Handle<Value> Buffer::dump(const Arguments& args) { - HandleScope scope; - Buffer* b = node::ObjectWrap::Unwrap<Buffer>(args.This()); - std::ostringstream ss; - osmium::osm::Dump dump(ss); - osmium::apply(b->buf, dump); - Local<String> obj = String::New(ss.str().c_str()); - return scope.Close(obj); - } - -} // namespace node_osmium - diff --git a/src/file_wrap.cpp b/src/file_wrap.cpp index c3abc55..64ea8e0 100644 --- a/src/file_wrap.cpp +++ b/src/file_wrap.cpp @@ -1,4 +1,10 @@ +// c++ +#include <exception> + +// v8 +#include <v8.h> + #include "file_wrap.hpp" namespace node_osmium { @@ -13,11 +19,6 @@ namespace node_osmium { target->Set(String::NewSymbol("File"), constructor->GetFunction()); } - FileWrap::FileWrap(const std::string& filename, const std::string& format) : - ObjectWrap(), - this_(std::make_shared<osmium::io::File>(filename, format)) { - } - Handle<Value> FileWrap::New(const Arguments& args) { HandleScope scope; if (!args.IsConstructCall()) { diff --git a/src/file_wrap.hpp b/src/file_wrap.hpp index 6a521c6..70ff142 100644 --- a/src/file_wrap.hpp +++ b/src/file_wrap.hpp @@ -1,8 +1,7 @@ #ifndef FILE_WRAP_HPP #define FILE_WRAP_HPP -// c++11 -#include <exception> +// c++ #include <memory> #include <string> @@ -10,8 +9,6 @@ #include <v8.h> // node.js -#include <node.h> -#include <node_version.h> #include <node_object_wrap.h> // osmium @@ -31,18 +28,13 @@ namespace node_osmium { static void Initialize(Handle<Object> target); static Handle<Value> New(const Arguments& args); - FileWrap(const std::string& filename = "", const std::string& format = ""); - - void _ref() { - Ref(); - } - - void _unref() { - Unref(); + FileWrap(const std::string& filename, const std::string& format) : + ObjectWrap(), + m_this(std::make_shared<osmium::io::File>(filename, format)) { } file_ptr get() { - return this_; + return m_this; } private: @@ -50,7 +42,7 @@ namespace node_osmium { ~FileWrap() { } - file_ptr this_; + file_ptr m_this; }; diff --git a/src/handler.cpp b/src/handler.cpp index 77d52c9..e842c17 100644 --- a/src/handler.cpp +++ b/src/handler.cpp @@ -1,4 +1,18 @@ +// c++ +#include <string> + +// v8 +#include <v8.h> + +// node +#include <node.h> +#include <node_object_wrap.h> + +// osmium +#include <osmium/osm/object.hpp> + +// node-osmium #include "handler.hpp" #include "osm_node_wrap.hpp" #include "osm_way_wrap.hpp" @@ -95,6 +109,41 @@ namespace node_osmium { handler->relation_cb.Dispose(); } handler->relation_cb = Persistent<Function>::New(callback); + } else if (callback_name == "init") { + if (!handler->init_cb.IsEmpty()) { + handler->init_cb.Dispose(); + } + handler->init_cb = Persistent<Function>::New(callback); + } else if (callback_name == "before_nodes") { + if (!handler->before_nodes_cb.IsEmpty()) { + handler->before_nodes_cb.Dispose(); + } + handler->before_nodes_cb = Persistent<Function>::New(callback); + } else if (callback_name == "after_nodes") { + if (!handler->after_nodes_cb.IsEmpty()) { + handler->after_nodes_cb.Dispose(); + } + handler->after_nodes_cb = Persistent<Function>::New(callback); + } else if (callback_name == "before_ways") { + if (!handler->before_ways_cb.IsEmpty()) { + handler->before_ways_cb.Dispose(); + } + handler->before_ways_cb = Persistent<Function>::New(callback); + } else if (callback_name == "after_ways") { + if (!handler->after_ways_cb.IsEmpty()) { + handler->after_ways_cb.Dispose(); + } + handler->after_ways_cb = Persistent<Function>::New(callback); + } else if (callback_name == "before_relations") { + if (!handler->before_relations_cb.IsEmpty()) { + handler->before_relations_cb.Dispose(); + } + handler->before_relations_cb = Persistent<Function>::New(callback); + } else if (callback_name == "after_relations") { + if (!handler->after_relations_cb.IsEmpty()) { + handler->after_relations_cb.Dispose(); + } + handler->after_relations_cb = Persistent<Function>::New(callback); } else if (callback_name == "done") { if (!handler->done_cb.IsEmpty()) { handler->done_cb.Dispose(); @@ -104,7 +153,7 @@ namespace node_osmium { return scope.Close(Undefined()); } - void JSHandler::dispatch_object(const osmium::io::InputIterator<osmium::io::Reader, osmium::Object>& it) { + void JSHandler::dispatch_object(const input_iterator& it) { HandleScope scope; switch (it->type()) { case osmium::item_type::node: @@ -166,5 +215,145 @@ namespace node_osmium { } } + void JSHandler::init() { + if (!init_cb.IsEmpty()) { + Local<Value> argv[0] = { }; + TryCatch trycatch; + Handle<Value> v = init_cb->Call(Context::GetCurrent()->Global(), 0, argv); + if (v.IsEmpty()) { + Handle<Value> exception = trycatch.Exception(); + String::AsciiValue exception_str(exception); + printf("Exception: %s\n", *exception_str); + exit(1); + } + } + } + + void JSHandler::before_nodes() { + if (!before_nodes_cb.IsEmpty()) { + Local<Value> argv[0] = { }; + TryCatch trycatch; + Handle<Value> v = before_nodes_cb->Call(Context::GetCurrent()->Global(), 0, argv); + if (v.IsEmpty()) { + Handle<Value> exception = trycatch.Exception(); + String::AsciiValue exception_str(exception); + printf("Exception: %s\n", *exception_str); + exit(1); + } + } + } + + void JSHandler::after_nodes() { + if (!after_nodes_cb.IsEmpty()) { + Local<Value> argv[0] = { }; + TryCatch trycatch; + Handle<Value> v = after_nodes_cb->Call(Context::GetCurrent()->Global(), 0, argv); + if (v.IsEmpty()) { + Handle<Value> exception = trycatch.Exception(); + String::AsciiValue exception_str(exception); + printf("Exception: %s\n", *exception_str); + exit(1); + } + } + } + + void JSHandler::before_ways() { + if (!before_ways_cb.IsEmpty()) { + Local<Value> argv[0] = { }; + TryCatch trycatch; + Handle<Value> v = before_ways_cb->Call(Context::GetCurrent()->Global(), 0, argv); + if (v.IsEmpty()) { + Handle<Value> exception = trycatch.Exception(); + String::AsciiValue exception_str(exception); + printf("Exception: %s\n", *exception_str); + exit(1); + } + } + } + + void JSHandler::after_ways() { + if (!after_ways_cb.IsEmpty()) { + Local<Value> argv[0] = { }; + TryCatch trycatch; + Handle<Value> v = after_ways_cb->Call(Context::GetCurrent()->Global(), 0, argv); + if (v.IsEmpty()) { + Handle<Value> exception = trycatch.Exception(); + String::AsciiValue exception_str(exception); + printf("Exception: %s\n", *exception_str); + exit(1); + } + } + } + + void JSHandler::before_relations() { + if (!before_relations_cb.IsEmpty()) { + Local<Value> argv[0] = { }; + TryCatch trycatch; + Handle<Value> v = before_relations_cb->Call(Context::GetCurrent()->Global(), 0, argv); + if (v.IsEmpty()) { + Handle<Value> exception = trycatch.Exception(); + String::AsciiValue exception_str(exception); + printf("Exception: %s\n", *exception_str); + exit(1); + } + } + } + + void JSHandler::after_relations() { + if (!after_relations_cb.IsEmpty()) { + Local<Value> argv[0] = { }; + TryCatch trycatch; + Handle<Value> v = after_relations_cb->Call(Context::GetCurrent()->Global(), 0, argv); + if (v.IsEmpty()) { + Handle<Value> exception = trycatch.Exception(); + String::AsciiValue exception_str(exception); + printf("Exception: %s\n", *exception_str); + exit(1); + } + } + } + + void JSHandler::before_changesets() { + if (!before_changesets_cb.IsEmpty()) { + Local<Value> argv[0] = { }; + TryCatch trycatch; + Handle<Value> v = before_changesets_cb->Call(Context::GetCurrent()->Global(), 0, argv); + if (v.IsEmpty()) { + Handle<Value> exception = trycatch.Exception(); + String::AsciiValue exception_str(exception); + printf("Exception: %s\n", *exception_str); + exit(1); + } + } + } + + void JSHandler::after_changesets() { + if (!after_changesets_cb.IsEmpty()) { + Local<Value> argv[0] = { }; + TryCatch trycatch; + Handle<Value> v = after_changesets_cb->Call(Context::GetCurrent()->Global(), 0, argv); + if (v.IsEmpty()) { + Handle<Value> exception = trycatch.Exception(); + String::AsciiValue exception_str(exception); + printf("Exception: %s\n", *exception_str); + exit(1); + } + } + } + + void JSHandler::done() { + if (!done_cb.IsEmpty()) { + Local<Value> argv[0] = { }; + TryCatch trycatch; + Handle<Value> v = done_cb->Call(Context::GetCurrent()->Global(), 0, argv); + if (v.IsEmpty()) { + Handle<Value> exception = trycatch.Exception(); + String::AsciiValue exception_str(exception); + printf("Exception: %s\n", *exception_str); + exit(1); + } + } + } + } // namespace node_osmium diff --git a/src/handler.hpp b/src/handler.hpp index 351f319..d529bc7 100644 --- a/src/handler.hpp +++ b/src/handler.hpp @@ -1,22 +1,12 @@ -// c++11 -#include <string> // v8 #include <v8.h> // node.js -#include <node.h> -#include <node_version.h> #include <node_object_wrap.h> -#include <node_buffer.h> -// osmium -#include <osmium/handler.hpp> -#include <osmium/osm.hpp> -#include <osmium/io/input_iterator.hpp> -#include <osmium/io/reader.hpp> -#include <osmium/geom/wkb.hpp> -#include <osmium/geom/wkt.hpp> +// node-osmium +#include "osm_object_wrap.hpp" namespace node_osmium { @@ -33,27 +23,39 @@ namespace node_osmium { static Handle<Value> options(const Arguments& args); JSHandler(); - void _ref() { - Ref(); - } + void dispatch_object(const input_iterator& it); - void _unref() { - Unref(); - } + void init(); + void before_nodes(); + void after_nodes(); + void before_ways(); + void after_ways(); + void before_relations(); + void after_relations(); + void before_changesets(); + void after_changesets(); + void done(); - void dispatch_object(const osmium::io::InputIterator<osmium::io::Reader, osmium::Object>& it); + bool node_callback_for_tagged_only; - void done() { - if (!done_cb.IsEmpty()) { - Local<Value> argv[0] = { }; - done_cb->Call(Context::GetCurrent()->Global(), 0, argv); - } - } + Persistent<Function> init_cb; - bool node_callback_for_tagged_only; + Persistent<Function> before_nodes_cb; Persistent<Function> node_cb; + Persistent<Function> after_nodes_cb; + + Persistent<Function> before_ways_cb; Persistent<Function> way_cb; + Persistent<Function> after_ways_cb; + + Persistent<Function> before_relations_cb; Persistent<Function> relation_cb; + Persistent<Function> after_relations_cb; + + Persistent<Function> before_changesets_cb; + Persistent<Function> changeset_cb; + Persistent<Function> after_changesets_cb; + Persistent<Function> done_cb; private: diff --git a/src/location_handler_wrap.cpp b/src/location_handler_wrap.cpp new file mode 100644 index 0000000..617df2c --- /dev/null +++ b/src/location_handler_wrap.cpp @@ -0,0 +1,38 @@ + +#include "location_handler_wrap.hpp" + +namespace node_osmium { + + Persistent<FunctionTemplate> LocationHandlerWrap::constructor; + + void LocationHandlerWrap::Initialize(Handle<Object> target) { + HandleScope scope; + constructor = Persistent<FunctionTemplate>::New(FunctionTemplate::New(LocationHandlerWrap::New)); + constructor->InstanceTemplate()->SetInternalFieldCount(1); + constructor->SetClassName(String::NewSymbol("LocationHandler")); + NODE_SET_PROTOTYPE_METHOD(constructor, "clear", clear); + target->Set(String::NewSymbol("LocationHandler"), constructor->GetFunction()); + } + + Handle<Value> LocationHandlerWrap::New(const Arguments& args) { + HandleScope scope; + try { + if (!args.IsConstructCall()) { + return ThrowException(Exception::Error(String::New("Cannot call constructor as function, you need to use 'new' keyword"))); + } + LocationHandlerWrap* q = new LocationHandlerWrap(); + q->Wrap(args.This()); + return args.This(); + } catch (const std::exception& ex) { + return ThrowException(Exception::TypeError(String::New(ex.what()))); + } + } + + Handle<Value> LocationHandlerWrap::clear(const Arguments& args) { + HandleScope scope; + // XXX do something here + return scope.Close(Undefined()); + } + +} // namespace node_osmium + diff --git a/src/location_handler_wrap.hpp b/src/location_handler_wrap.hpp new file mode 100644 index 0000000..4d058ad --- /dev/null +++ b/src/location_handler_wrap.hpp @@ -0,0 +1,75 @@ +#ifndef LOCATION_HANDLER_WRAP_HPP +#define LOCATION_HANDLER_WRAP_HPP + +// c++ +#include <memory> + +// v8 +#include <v8.h> + +// node.js +#include <node_object_wrap.h> + +// osmium +#include <osmium/handler/node_locations_for_ways.hpp> +#include <osmium/index/map/dummy.hpp> +#include <osmium/index/map/stl_map.hpp> +#include <osmium/index/map/sparse_table.hpp> + +using namespace v8; + +namespace node_osmium { + + typedef osmium::index::map::Dummy<osmium::unsigned_object_id_type, osmium::Location> index_neg_type; + typedef osmium::index::map::SparseTable<osmium::unsigned_object_id_type, osmium::Location> index_pos_type; + typedef osmium::handler::NodeLocationsForWays<index_pos_type, index_neg_type> location_handler_type; + + typedef std::shared_ptr<location_handler_type> location_handler_ptr; + + class LocationHandlerWrap : public node::ObjectWrap { + + public: + + static Persistent<FunctionTemplate> constructor; + + static void Initialize(Handle<Object> target); + static Handle<Value> New(const Arguments& args); + static Handle<Value> clear(const Arguments& args); + + static location_handler_type& wrapped(Local<Object> object) { + return *(node::ObjectWrap::Unwrap<LocationHandlerWrap>(object)->get()); + } + + LocationHandlerWrap() : + ObjectWrap(), + m_index_pos(), + m_index_neg(), + m_this(std::make_shared<location_handler_type>(m_index_pos, m_index_neg)) { + } + + void _ref() { + Ref(); + } + + void _unref() { + Unref(); + } + + location_handler_ptr get() { + return m_this; + } + + private: + + ~LocationHandlerWrap() { + } + + index_pos_type m_index_pos; + index_neg_type m_index_neg; + location_handler_ptr m_this; + + }; + +} // namespace node_osmium + +#endif // LOCATION_HANDLER_WRAP_HPP diff --git a/src/node_osmium.cpp b/src/node_osmium.cpp index 268d67c..5d6b456 100644 --- a/src/node_osmium.cpp +++ b/src/node_osmium.cpp @@ -13,9 +13,9 @@ #include "osm_way_wrap.hpp" #include "osm_relation_wrap.hpp" #include "handler.hpp" +#include "location_handler_wrap.hpp" #include "file_wrap.hpp" #include "reader_wrap.hpp" -#include "buffer.hpp" namespace node_osmium { @@ -25,8 +25,8 @@ namespace node_osmium { node_osmium::OSMNodeWrap::Initialize(target); node_osmium::OSMWayWrap::Initialize(target); node_osmium::OSMRelationWrap::Initialize(target); + node_osmium::LocationHandlerWrap::Initialize(target); node_osmium::JSHandler::Initialize(target); -// node_osmium::Buffer::Initialize(target); node_osmium::FileWrap::Initialize(target); node_osmium::ReaderWrap::Initialize(target); } diff --git a/src/osm_node_wrap.cpp b/src/osm_node_wrap.cpp index d67b3c9..82ba6bc 100644 --- a/src/osm_node_wrap.cpp +++ b/src/osm_node_wrap.cpp @@ -19,6 +19,17 @@ namespace node_osmium { NODE_SET_PROTOTYPE_METHOD(constructor, "tags", tags); NODE_SET_PROTOTYPE_METHOD(constructor, "wkb", wkb); NODE_SET_PROTOTYPE_METHOD(constructor, "wkt", wkt); + enum PropertyAttribute attributes = + static_cast<PropertyAttribute>(v8::ReadOnly | v8::DontDelete); + SET_ACCESSOR(constructor, "id", get_id, attributes); + SET_ACCESSOR(constructor, "version", get_version, attributes); + SET_ACCESSOR(constructor, "changeset", get_changeset, attributes); + SET_ACCESSOR(constructor, "visible", get_visible, attributes); + SET_ACCESSOR(constructor, "timestamp", get_timestamp, attributes); + SET_ACCESSOR(constructor, "uid", get_uid, attributes); + SET_ACCESSOR(constructor, "user", get_user, attributes); + SET_ACCESSOR(constructor, "lon", get_lon, attributes); + SET_ACCESSOR(constructor, "lat", get_lat, attributes); target->Set(String::NewSymbol("Node"), constructor->GetFunction()); } @@ -36,30 +47,27 @@ namespace node_osmium { void* ptr = ext->Value(); OSMNodeWrap* node = static_cast<OSMNodeWrap*>(ptr); node->Wrap(args.This()); - osmium::Node& obj = static_cast<osmium::Node&>(*(node->m_it)); - args.This()->Set(String::New("id"), Number::New(obj.id())); - args.This()->Set(String::New("version"), Number::New(obj.version())); - args.This()->Set(String::New("changeset"), Number::New(obj.changeset())); - args.This()->Set(String::New("visible"), Boolean::New(obj.visible())); - args.This()->Set(String::New("timestamp"), Number::New(obj.timestamp())); - args.This()->Set(String::New("timestamp_iso"), String::New(obj.timestamp().to_iso().c_str(), obj.timestamp().to_iso().size())); - args.This()->Set(String::New("uid"), Number::New(obj.uid())); - args.This()->Set(String::New("user"), String::New(obj.user())); - args.This()->Set(String::New("lon"), Number::New(obj.lon())); - args.This()->Set(String::New("lat"), Number::New(obj.lat())); - return args.This(); } else { return ThrowException(Exception::TypeError(String::New("osmium.Node cannot be created in Javascript"))); } - return Undefined(); + return scope.Close(Undefined()); + } + + Handle<Value> OSMNodeWrap::get_lon(Local<String> property,const AccessorInfo& info) { + HandleScope scope; + return scope.Close(Number::New(wrapped(info.This()).lon())); + } + + Handle<Value> OSMNodeWrap::get_lat(Local<String> property,const AccessorInfo& info) { + HandleScope scope; + return scope.Close(Number::New(wrapped(info.This()).lat())); } Handle<Value> OSMNodeWrap::wkb(const Arguments& args) { HandleScope scope; - osmium::Node& node = static_cast<osmium::Node&>(*(node::ObjectWrap::Unwrap<OSMNodeWrap>(args.This())->m_it)); - std::string wkb { wkb_factory.create_point(node) }; + std::string wkb { wkb_factory.create_point(wrapped(args.This())) }; #if NODE_VERSION_AT_LEAST(0, 10, 0) return scope.Close(node::Buffer::New(wkb.data(), wkb.size())->handle_); #else @@ -69,9 +77,8 @@ namespace node_osmium { Handle<Value> OSMNodeWrap::wkt(const Arguments& args) { HandleScope scope; - osmium::Node& node = static_cast<osmium::Node&>(*(node::ObjectWrap::Unwrap<OSMNodeWrap>(args.This())->m_it)); - std::string wkt { wkt_factory.create_point(node) }; + std::string wkt { wkt_factory.create_point(wrapped(args.This())) }; return scope.Close(String::New(wkt.c_str())); } diff --git a/src/osm_node_wrap.hpp b/src/osm_node_wrap.hpp index 4994f01..0a92d4f 100644 --- a/src/osm_node_wrap.hpp +++ b/src/osm_node_wrap.hpp @@ -30,18 +30,17 @@ namespace node_osmium { static Handle<Value> New(const Arguments& args); static Handle<Value> wkb(const Arguments& args); static Handle<Value> wkt(const Arguments& args); - OSMNodeWrap(const input_iterator&); + static Handle<Value> get_lon(Local<String> property,const AccessorInfo& info); + static Handle<Value> get_lat(Local<String> property,const AccessorInfo& info); - void _ref() { - Ref(); + static osmium::Node& wrapped(Local<Object> object) { + return static_cast<osmium::Node&>(OSMObjectWrap::wrapped(object)); } - void _unref() { - Unref(); - } + OSMNodeWrap(const input_iterator&); osmium::Node& object() { - return static_cast<osmium::Node&>(*m_it); + return static_cast<osmium::Node&>(*get()); } private: diff --git a/src/osm_object_wrap.cpp b/src/osm_object_wrap.cpp index 0caacc4..f5801b4 100644 --- a/src/osm_object_wrap.cpp +++ b/src/osm_object_wrap.cpp @@ -25,4 +25,39 @@ namespace node_osmium { return Undefined(); } + Handle<Value> OSMObjectWrap::get_id(Local<String> property,const AccessorInfo& info) { + HandleScope scope; + return scope.Close(Number::New(wrapped(info.This()).id())); + } + + Handle<Value> OSMObjectWrap::get_version(Local<String> property,const AccessorInfo& info) { + HandleScope scope; + return scope.Close(Number::New(wrapped(info.This()).version())); + } + + Handle<Value> OSMObjectWrap::get_changeset(Local<String> property,const AccessorInfo& info) { + HandleScope scope; + return scope.Close(Number::New(wrapped(info.This()).changeset())); + } + + Handle<Value> OSMObjectWrap::get_visible(Local<String> property,const AccessorInfo& info) { + HandleScope scope; + return scope.Close(Boolean::New(wrapped(info.This()).visible())); + } + + Handle<Value> OSMObjectWrap::get_timestamp(Local<String> property,const AccessorInfo& info) { + HandleScope scope; + return scope.Close(Number::New(wrapped(info.This()).timestamp())); + } + + Handle<Value> OSMObjectWrap::get_uid(Local<String> property,const AccessorInfo& info) { + HandleScope scope; + return scope.Close(Number::New(wrapped(info.This()).uid())); + } + + Handle<Value> OSMObjectWrap::get_user(Local<String> property,const AccessorInfo& info) { + HandleScope scope; + return scope.Close(String::New(wrapped(info.This()).user())); + } + } // namespace node_osmium diff --git a/src/osm_object_wrap.hpp b/src/osm_object_wrap.hpp index 805d3e7..e5fd50a 100644 --- a/src/osm_object_wrap.hpp +++ b/src/osm_object_wrap.hpp @@ -17,24 +17,41 @@ using namespace v8; +#define SET_ACCESSOR(t, name, getter,attributes) \ + t->InstanceTemplate()->SetAccessor(String::NewSymbol(name),getter,NULL,Handle<Value>(),v8::DEFAULT,attributes); \ + + namespace node_osmium { typedef osmium::io::InputIterator<osmium::io::Reader, osmium::Object> input_iterator; class OSMObjectWrap : public node::ObjectWrap { - protected: - input_iterator m_it; public: static Handle<Value> tags(const Arguments& args); + static Handle<Value> get_id(Local<String> property,const AccessorInfo& info); + static Handle<Value> get_version(Local<String> property,const AccessorInfo& info); + static Handle<Value> get_changeset(Local<String> property,const AccessorInfo& info); + static Handle<Value> get_visible(Local<String> property,const AccessorInfo& info); + static Handle<Value> get_timestamp(Local<String> property,const AccessorInfo& info); + static Handle<Value> get_uid(Local<String> property,const AccessorInfo& info); + static Handle<Value> get_user(Local<String> property,const AccessorInfo& info); + + static osmium::Object& wrapped(Local<Object> object) { + return *(node::ObjectWrap::Unwrap<OSMObjectWrap>(object)->get()); + } OSMObjectWrap(const input_iterator& it) : m_it(it) { } + input_iterator& get() { + return m_it; + } + }; // class OSMObjectWrap } // namespace node_osmium diff --git a/src/osm_relation_wrap.cpp b/src/osm_relation_wrap.cpp index 1c16b16..21e7d60 100644 --- a/src/osm_relation_wrap.cpp +++ b/src/osm_relation_wrap.cpp @@ -12,6 +12,15 @@ namespace node_osmium { constructor->SetClassName(String::NewSymbol("Relation")); NODE_SET_PROTOTYPE_METHOD(constructor, "tags", tags); NODE_SET_PROTOTYPE_METHOD(constructor, "members", members); + enum PropertyAttribute attributes = + static_cast<PropertyAttribute>(v8::ReadOnly | v8::DontDelete); + SET_ACCESSOR(constructor, "id", get_id, attributes); + SET_ACCESSOR(constructor, "version", get_version, attributes); + SET_ACCESSOR(constructor, "changeset", get_changeset, attributes); + SET_ACCESSOR(constructor, "visible", get_visible, attributes); + SET_ACCESSOR(constructor, "timestamp", get_timestamp, attributes); + SET_ACCESSOR(constructor, "uid", get_uid, attributes); + SET_ACCESSOR(constructor, "user", get_user, attributes); target->Set(String::NewSymbol("Relation"), constructor->GetFunction()); } @@ -29,15 +38,6 @@ namespace node_osmium { void* ptr = ext->Value(); OSMRelationWrap* relation = static_cast<OSMRelationWrap*>(ptr); relation->Wrap(args.This()); - osmium::Relation& obj = static_cast<osmium::Relation&>(*(relation->m_it)); - args.This()->Set(String::New("id"), Number::New(obj.id())); - args.This()->Set(String::New("version"), Number::New(obj.version())); - args.This()->Set(String::New("changeset"), Number::New(obj.changeset())); - args.This()->Set(String::New("visible"), Boolean::New(obj.visible())); - args.This()->Set(String::New("timestamp"), Number::New(obj.timestamp())); - args.This()->Set(String::New("timestamp_iso"), String::New(obj.timestamp().to_iso().c_str(), obj.timestamp().to_iso().size())); - args.This()->Set(String::New("uid"), Number::New(obj.uid())); - args.This()->Set(String::New("user"), String::New(obj.user())); return args.This(); } else { return ThrowException(Exception::TypeError(String::New("osmium.Relation cannot be created in Javascript"))); @@ -47,7 +47,7 @@ namespace node_osmium { Handle<Value> OSMRelationWrap::members(const Arguments& args) { HandleScope scope; - osmium::Relation& relation = static_cast<osmium::Relation&>(*(node::ObjectWrap::Unwrap<OSMRelationWrap>(args.This())->m_it)); + osmium::Relation& relation = wrapped(args.This()); if (args.Length() == 0) { Local<Array> members = Array::New(); diff --git a/src/osm_relation_wrap.hpp b/src/osm_relation_wrap.hpp index d65877e..60386b3 100644 --- a/src/osm_relation_wrap.hpp +++ b/src/osm_relation_wrap.hpp @@ -31,18 +31,15 @@ namespace node_osmium { static void Initialize(Handle<Object> target); static Handle<Value> New(const Arguments& args); static Handle<Value> members(const Arguments& args); - OSMRelationWrap(const input_iterator&); - void _ref() { - Ref(); + static osmium::Relation& wrapped(Local<Object> object) { + return static_cast<osmium::Relation&>(OSMObjectWrap::wrapped(object)); } - void _unref() { - Unref(); - } + OSMRelationWrap(const input_iterator&); osmium::Relation& object() { - return static_cast<osmium::Relation&>(*m_it); + return static_cast<osmium::Relation&>(*get()); } private: diff --git a/src/osm_way_wrap.cpp b/src/osm_way_wrap.cpp index a3a3723..d3be9e7 100644 --- a/src/osm_way_wrap.cpp +++ b/src/osm_way_wrap.cpp @@ -20,6 +20,15 @@ namespace node_osmium { NODE_SET_PROTOTYPE_METHOD(constructor, "wkb", wkb); NODE_SET_PROTOTYPE_METHOD(constructor, "wkt", wkt); NODE_SET_PROTOTYPE_METHOD(constructor, "nodes", nodes); + enum PropertyAttribute attributes = + static_cast<PropertyAttribute>(v8::ReadOnly | v8::DontDelete); + SET_ACCESSOR(constructor, "id", get_id, attributes); + SET_ACCESSOR(constructor, "version", get_version, attributes); + SET_ACCESSOR(constructor, "changeset", get_changeset, attributes); + SET_ACCESSOR(constructor, "visible", get_visible, attributes); + SET_ACCESSOR(constructor, "timestamp", get_timestamp, attributes); + SET_ACCESSOR(constructor, "uid", get_uid, attributes); + SET_ACCESSOR(constructor, "user", get_user, attributes); target->Set(String::NewSymbol("Way"), constructor->GetFunction()); } @@ -37,15 +46,6 @@ namespace node_osmium { void* ptr = ext->Value(); OSMWayWrap* way = static_cast<OSMWayWrap*>(ptr); way->Wrap(args.This()); - osmium::Way& obj = static_cast<osmium::Way&>(*(way->m_it)); - args.This()->Set(String::New("id"), Number::New(obj.id())); - args.This()->Set(String::New("version"), Number::New(obj.version())); - args.This()->Set(String::New("changeset"), Number::New(obj.changeset())); - args.This()->Set(String::New("visible"), Boolean::New(obj.visible())); - args.This()->Set(String::New("timestamp"), Number::New(obj.timestamp())); - args.This()->Set(String::New("timestamp_iso"), String::New(obj.timestamp().to_iso().c_str(), obj.timestamp().to_iso().size())); - args.This()->Set(String::New("uid"), Number::New(obj.uid())); - args.This()->Set(String::New("user"), String::New(obj.user())); return args.This(); } else { return ThrowException(Exception::TypeError(String::New("osmium.Way cannot be created in Javascript"))); @@ -55,10 +55,9 @@ namespace node_osmium { Handle<Value> OSMWayWrap::wkb(const Arguments& args) { HandleScope scope; - osmium::Way& way = static_cast<osmium::Way&>(*(node::ObjectWrap::Unwrap<OSMWayWrap>(args.This())->m_it)); try { - std::string wkb { wkb_factory.create_linestring(way) }; + std::string wkb { wkb_factory.create_linestring(wrapped(args.This())) }; #if NODE_VERSION_AT_LEAST(0, 10, 0) return scope.Close(node::Buffer::New(wkb.data(), wkb.size())->handle_); #else @@ -71,10 +70,9 @@ namespace node_osmium { Handle<Value> OSMWayWrap::wkt(const Arguments& args) { HandleScope scope; - osmium::Way& way = static_cast<osmium::Way&>(*(node::ObjectWrap::Unwrap<OSMWayWrap>(args.This())->m_it)); try { - std::string wkt { wkt_factory.create_linestring(way) }; + std::string wkt { wkt_factory.create_linestring(wrapped(args.This())) }; return scope.Close(String::New(wkt.c_str())); } catch (osmium::geom::geometry_error&) { return scope.Close(Undefined()); @@ -83,7 +81,7 @@ namespace node_osmium { Handle<Value> OSMWayWrap::nodes(const Arguments& args) { HandleScope scope; - osmium::Way& way = static_cast<osmium::Way&>(*(node::ObjectWrap::Unwrap<OSMWayWrap>(args.This())->m_it)); + osmium::Way& way = static_cast<osmium::Way&>(*(node::ObjectWrap::Unwrap<OSMWayWrap>(args.This())->get())); if (args.Length() == 0) { Local<Array> nodes = Array::New(way.nodes().size()); diff --git a/src/osm_way_wrap.hpp b/src/osm_way_wrap.hpp index 9de530e..d381acc 100644 --- a/src/osm_way_wrap.hpp +++ b/src/osm_way_wrap.hpp @@ -30,18 +30,15 @@ namespace node_osmium { static Handle<Value> wkb(const Arguments& args); static Handle<Value> wkt(const Arguments& args); static Handle<Value> nodes(const Arguments& args); - OSMWayWrap(const input_iterator&); - void _ref() { - Ref(); + static osmium::Way& wrapped(Local<Object> object) { + return static_cast<osmium::Way&>(OSMObjectWrap::wrapped(object)); } - void _unref() { - Unref(); - } + OSMWayWrap(const input_iterator&); osmium::Way& object() { - return static_cast<osmium::Way&>(*m_it); + return static_cast<osmium::Way&>(*get()); } private: diff --git a/src/reader_wrap.cpp b/src/reader_wrap.cpp index 73f6c2b..d9e4884 100644 --- a/src/reader_wrap.cpp +++ b/src/reader_wrap.cpp @@ -1,7 +1,25 @@ +// c++ +#include <exception> +#include <string> +#include <vector> + +// boost +#include <boost/variant.hpp> + +// node.js +#include <node.h> +#include <node_object_wrap.h> + +// osmium +#include <osmium/visitor.hpp> + +// node-osmium #include "reader_wrap.hpp" #include "file_wrap.hpp" #include "handler.hpp" +#include "location_handler_wrap.hpp" +#include "osm_object_wrap.hpp" namespace node_osmium { @@ -18,14 +36,6 @@ namespace node_osmium { target->Set(String::NewSymbol("Reader"), constructor->GetFunction()); } - ReaderWrap::ReaderWrap(osmium::io::File& file, osmium::osm_entity::flags entities) : - ObjectWrap(), - this_(std::make_shared<osmium::io::Reader>(file, entities)), - header_(this_->header()) { - } - - ReaderWrap::~ReaderWrap() { } - Handle<Value> ReaderWrap::New(const Arguments& args) { HandleScope scope; if (!args.IsConstructCall()) { @@ -83,7 +93,7 @@ namespace node_osmium { HandleScope scope; Local<Object> obj = Object::New(); ReaderWrap* reader = node::ObjectWrap::Unwrap<ReaderWrap>(args.This()); - const osmium::io::Header& header = reader->header_; + const osmium::io::Header& header = reader->m_this->header(); obj->Set(String::New("generator"), String::New(header.get("generator").c_str())); const osmium::Box& bounds = header.box(); Local<Array> arr = Array::New(4); @@ -95,69 +105,131 @@ namespace node_osmium { return scope.Close(obj); } - Handle<Value> ReaderWrap::apply(const Arguments& args) { - HandleScope scope; + struct visitor_type : public boost::static_visitor<> { + + input_iterator& m_it; - if (args.Length() != 1 && args.Length() != 2) { - return ThrowException(Exception::TypeError(String::New("please provide a single handler object"))); + visitor_type(input_iterator& it) : + m_it(it) { } - if (!args[0]->IsObject()) { - return ThrowException(Exception::TypeError(String::New("please provide a single handler object"))); + + void operator()(JSHandler& handler) const { + handler.dispatch_object(m_it); } - Local<Object> obj = args[0]->ToObject(); - if (obj->IsNull() || obj->IsUndefined() || !JSHandler::constructor->HasInstance(obj)) { - return ThrowException(Exception::TypeError(String::New("please provide a valid handler object"))); + + void operator()(location_handler_type& handler) const { + osmium::apply_item(*m_it, handler); } - bool with_location_handler = false; + }; // visitor_type + + struct visitor_before_after_type : public boost::static_visitor<> { + + osmium::item_type m_last; + osmium::item_type m_current; + + visitor_before_after_type(osmium::item_type last, osmium::item_type current) : + m_last(last), + m_current(current) { + } - if (args.Length() == 2) { - if (!args[1]->IsObject()) { - return ThrowException(Exception::TypeError(String::New("second argument must be 'option' object"))); + template <class TVisitor> + void operator()(TVisitor& visitor) const { + switch (m_last) { + case osmium::item_type::undefined: + visitor.init(); + break; + case osmium::item_type::node: + visitor.after_nodes(); + break; + case osmium::item_type::way: + visitor.after_ways(); + break; + case osmium::item_type::relation: + visitor.after_relations(); + break; + case osmium::item_type::changeset: + visitor.after_changesets(); + break; + default: + break; } - Local<Value> wlh = args[1]->ToObject()->Get(String::New("with_location_handler")); - if (wlh->BooleanValue()) { - with_location_handler = true; + switch (m_current) { + case osmium::item_type::undefined: + visitor.done(); + break; + case osmium::item_type::node: + visitor.before_nodes(); + break; + case osmium::item_type::way: + visitor.before_ways(); + break; + case osmium::item_type::relation: + visitor.before_relations(); + break; + case osmium::item_type::changeset: + visitor.before_changesets(); + break; + default: + break; } } - JSHandler* handler = node::ObjectWrap::Unwrap<JSHandler>(obj); - ReaderWrap* reader = node::ObjectWrap::Unwrap<ReaderWrap>(args.This()); - reader_ptr r_ptr = reader->get(); - - if (with_location_handler) { - index_pos_type index_pos; - index_neg_type index_neg; - location_handler_type location_handler(index_pos, index_neg); + }; // visitor_before_after - osmium::io::InputIterator<osmium::io::Reader, osmium::Object> it(*r_ptr); - osmium::io::InputIterator<osmium::io::Reader, osmium::Object> end; + Handle<Value> ReaderWrap::apply(const Arguments& args) { + HandleScope scope; - for (; it != end; ++it) { - osmium::apply_item(*it, location_handler); - handler->dispatch_object(it); + typedef boost::variant<location_handler_type&, JSHandler&> some_handler_type; + std::vector<some_handler_type> handlers; + + for (int i=0; i != args.Length(); ++i) { + if (args[i]->IsObject()) { + Local<Object> obj = args[i]->ToObject(); + if (JSHandler::constructor->HasInstance(obj)) { + handlers.push_back(*node::ObjectWrap::Unwrap<JSHandler>(obj)); + } else if (LocationHandlerWrap::constructor->HasInstance(obj)) { + location_handler_type* lh = node::ObjectWrap::Unwrap<LocationHandlerWrap>(obj)->get().get(); + handlers.push_back(*lh); + } + } else { + return ThrowException(Exception::TypeError(String::New("please provide a handler object"))); } + } + + osmium::io::Reader& reader = wrapped(args.This()); - handler->done(); - } else { - osmium::io::InputIterator<osmium::io::Reader, osmium::Object> it(*r_ptr); - osmium::io::InputIterator<osmium::io::Reader, osmium::Object> end; + input_iterator it(reader); + input_iterator end; - for (; it != end; ++it) { - handler->dispatch_object(it); + osmium::item_type last_type = osmium::item_type::undefined; + + for (; it != end; ++it) { + visitor_before_after_type visitor_before_after(last_type, it->type()); + visitor_type visitor(it); + + for (some_handler_type& handler : handlers) { + if (last_type != it->type()) { + boost::apply_visitor(visitor_before_after, handler); + } + boost::apply_visitor(visitor, handler); + } + + if (last_type != it->type()) { + last_type = it->type(); } + } - handler->done(); + visitor_before_after_type visitor_before_after(last_type, osmium::item_type::undefined); + for (auto handler : handlers) { + boost::apply_visitor(visitor_before_after, handler); } return Undefined(); } Handle<Value> ReaderWrap::close(const Arguments& args) { - HandleScope scope; - ReaderWrap* reader = node::ObjectWrap::Unwrap<ReaderWrap>(args.This()); - reader_ptr r_ptr = reader->get(); - r_ptr->close(); + wrapped(args.This()).close(); return Undefined(); } diff --git a/src/reader_wrap.hpp b/src/reader_wrap.hpp index 2c4f757..11a8b95 100644 --- a/src/reader_wrap.hpp +++ b/src/reader_wrap.hpp @@ -1,30 +1,21 @@ #ifndef READER_WRAP_HPP #define READER_WRAP_HPP -// c++11 -#include <exception> +// c++ #include <memory> // v8 #include <v8.h> // node.js -#include <node.h> -#include <node_version.h> #include <node_object_wrap.h> // osmium #include <osmium/io/any_input.hpp> -#include <osmium/io/input_iterator.hpp> -#include <osmium/visitor.hpp> -#include <osmium/handler/node_locations_for_ways.hpp> -#include <osmium/index/map/dummy.hpp> -#include <osmium/index/map/stl_map.hpp> -#include <osmium/index/map/sparse_table.hpp> - -typedef osmium::index::map::Dummy<osmium::unsigned_object_id_type, osmium::Location> index_neg_type; -typedef osmium::index::map::SparseTable<osmium::unsigned_object_id_type, osmium::Location> index_pos_type; -typedef osmium::handler::NodeLocationsForWays<index_pos_type, index_neg_type> location_handler_type; +#include <osmium/io/reader.hpp> +#include <osmium/osm/entity_flags.hpp> +#include <osmium/osm/location.hpp> +#include <osmium/osm/types.hpp> using namespace v8; @@ -42,25 +33,26 @@ namespace node_osmium { static Handle<Value> header(const Arguments& args); static Handle<Value> apply(const Arguments& args); static Handle<Value> close(const Arguments& args); - ReaderWrap(osmium::io::File& infile, osmium::osm_entity::flags entities); - void _ref() { - Ref(); + static osmium::io::Reader& wrapped(Local<Object> object) { + return *(node::ObjectWrap::Unwrap<ReaderWrap>(object)->get()); } - void _unref() { - Unref(); + ReaderWrap(const osmium::io::File& file, osmium::osm_entity::flags entities) : + ObjectWrap(), + m_this(std::make_shared<osmium::io::Reader>(file, entities)) { } reader_ptr get() { - return this_; + return m_this; } private: - ~ReaderWrap(); - reader_ptr this_; - osmium::io::Header header_; + ~ReaderWrap() { + } + + reader_ptr m_this; }; } // namespace node_osmium diff --git a/test/osmium.test.js b/test/osmium.test.js index 40659f2..c5ea5c6 100644 --- a/test/osmium.test.js +++ b/test/osmium.test.js @@ -4,12 +4,12 @@ var assert = require('assert'); describe('osmium', function() { it('should be able to create an osmium.Reader', function(done) { - var file = new osmium.File(__dirname+"/data/berlin-latest.osm.pbf"); + var file = new osmium.File(__dirname+"/data/winthrop.osm"); var reader = new osmium.Reader(file, {}); var header = reader.header(); - assert.equal(header.generator, 'Osmium (http://wiki.openstreetmap.org/wiki/Osmium)'); + assert.equal(header.generator, 'CGImap 0.2.0'); var bounds = header.bounds; - var expected = [ 13.08283, 52.33446, 13.76136, 52.6783 ]; + var expected = [ -120.2024, 48.4636, -120.1569, 48.4869 ]; assert.ok(Math.abs(bounds[0] - expected[0]) < .000000001); assert.ok(Math.abs(bounds[1] - expected[1]) < .000000001); assert.ok(Math.abs(bounds[2] - expected[2]) < .000000001); @@ -18,28 +18,19 @@ describe('osmium', function() { done(); }); - it('should be able to apply a handler to a reader', function(done) { + it('should be able to read ISO time from node', function(done) { var handler = new osmium.Handler(); - var nodes = 0; + var count = 0; handler.on('node',function(node) { - ++nodes; - }); - handler.on('done',function() { - assert.equal(nodes >= 1993505, true); + if (count == 0) { + assert.equal(node.date().toISOString(),'2009-11-17T00:10:56.000Z'); + done(); + } + count++; }); - var file = new osmium.File(__dirname+"/data/berlin-latest.osm.pbf"); - var reader = new osmium.Reader(file); + var file = new osmium.File(__dirname+"/data/winthrop.osm"); + var reader = new osmium.Reader(file, {node:true}); reader.apply(handler); - - // since reader.apply is sync, we can re-use handlers - var file2 = new osmium.File(__dirname+"/data/winthrop.osm"); - var reader2 = new osmium.Reader(file2); - nodes = 0; - handler.on('done',function() { - assert.equal(nodes, 1525); - done(); - }); - reader2.apply(handler); }); it('should be able to get node data from handler parameter', function(done) { @@ -85,4 +76,75 @@ describe('osmium', function() { reader.apply(handler); }); + it('should be able to use location handler', function(done) { + var location_handler = new osmium.LocationHandler(); + var handler = new osmium.Handler(); + var ways = 0; + handler.on('way', function(way) { + if (ways == 0) { + assert.equal(way.wkt(), "LINESTRING(-120.1872774 48.4715898,-120.188291 48.472511,-120.188374 48.472591,-120.188496 48.472707,-120.188625 48.47283,-120.18914 48.473561)"); + } + ++ways; + }); + handler.on('done', function() { + done(); + }); + var reader = new osmium.Reader(__dirname+"/data/winthrop.osm", { 'node': true, 'way': true }); + reader.apply(location_handler, handler); + }); + + it('should be able to call before and after callbacks', function(done) { + var handler = new osmium.Handler(); + var nodes = 0; + var before_nodes = 0, after_nodes = 0; + + handler.on('init', function() { + assert.equal(nodes, 0); + }); + handler.on('before_nodes', function() { + assert.equal(nodes, 0); + before_nodes++; + }); + handler.on('node',function(node) { + ++nodes; + }); + handler.on('after_nodes', function() { + assert.equal(nodes >= 1500, true); + after_nodes++; + }); + handler.on('done',function() { + assert.equal(nodes >= 1500, true); + done(); + }); + + var file = new osmium.File(__dirname+"/data/winthrop.osm"); + var reader = new osmium.Reader(file); + reader.apply(handler); + + assert.equal(before_nodes, 1); + assert.equal(after_nodes, 1); + }); + + it('should be able to call two handlers one after the other', function(done) { + var handler1 = new osmium.Handler(); + var handler2 = new osmium.Handler(); + + var count=0; + handler1.on('init', function() { + assert.equal(count, 0); + count++; + }); + handler2.on('init', function() { + assert.equal(count, 1); + count++; + }); + + var file = new osmium.File(__dirname+"/data/winthrop.osm"); + var reader = new osmium.Reader(file); + reader.apply(handler1, handler2); + + assert.equal(count, 2); + done(); + }); + }); -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/node-osmium.git _______________________________________________ Pkg-grass-devel mailing list Pkg-grass-devel@lists.alioth.debian.org http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-grass-devel