From de2e1313f9e707ff765b981238bd9d57d94c0b0c Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Mon, 25 Jun 2018 14:46:54 -0700 Subject: [PATCH 1/3] re-implement #73 on top of latest master --- binding.gyp | 3 +++ scripts/install_deps.sh | 1 + scripts/setup.sh | 2 +- src/vtquery.cpp | 50 ++++++++++++++++++++++++++++++++--------- 4 files changed, 45 insertions(+), 11 deletions(-) diff --git a/binding.gyp b/binding.gyp index 6540cb7c..7277def8 100644 --- a/binding.gyp +++ b/binding.gyp @@ -63,6 +63,9 @@ './src/module.cpp', './src/vtquery.cpp' ], + 'link_settings': { + 'libraries': [ '-lz' ] + }, 'ldflags': [ '-Wl,-z,now', ], diff --git a/scripts/install_deps.sh b/scripts/install_deps.sh index df07500c..1b13958f 100755 --- a/scripts/install_deps.sh +++ b/scripts/install_deps.sh @@ -20,3 +20,4 @@ install spatial-algorithms 0.1.0 install boost 1.65.1 install cheap-ruler 2.5.3 install vector-tile f4728da +install gzip-hpp 0.1.0 diff --git a/scripts/setup.sh b/scripts/setup.sh index ea3130b8..fd1d34c3 100755 --- a/scripts/setup.sh +++ b/scripts/setup.sh @@ -3,7 +3,7 @@ set -eu set -o pipefail -export MASON_RELEASE="${MASON_RELEASE:-d7b7c17}" +export MASON_RELEASE="${MASON_RELEASE:-bca9fe4}" export MASON_LLVM_RELEASE="${MASON_LLVM_RELEASE:-5.0.0}" PLATFORM=$(uname | tr A-Z a-z) diff --git a/src/vtquery.cpp b/src/vtquery.cpp index 458c395e..1da79aca 100644 --- a/src/vtquery.cpp +++ b/src/vtquery.cpp @@ -15,6 +15,8 @@ #include #include #include +#include +#include namespace VectorTileQuery { @@ -28,9 +30,12 @@ const char* getGeomTypeString(int enumVal) { return GeomTypeStrings[enumVal]; } +using materialized_prop_type = std::pair; + /// main storage item for returning to the user struct ResultObject { std::vector properties_vector; + std::vector properties_vector_materialized; std::string layer_name; mapbox::geometry::point coordinates; double distance; @@ -39,6 +44,7 @@ struct ResultObject { uint64_t id; ResultObject() : properties_vector(), + properties_vector_materialized(), layer_name(), coordinates(0.0, 0.0), distance(std::numeric_limits::max()), @@ -150,11 +156,9 @@ struct property_value_visitor { }; /// used to create the final v8 (JSON) object to return to the user -void set_property(vtzero::property const& property, +void set_property(materialized_prop_type const& property, v8::Local& properties_obj) { - - auto val = vtzero::convert_property_value(property.value()); - mapbox::util::apply_visitor(property_value_visitor{properties_obj, std::string(property.key())}, val); + mapbox::util::apply_visitor(property_value_visitor{properties_obj, property.first}, property.second); } GeomType get_geometry_type(vtzero::feature const& f) { @@ -268,11 +272,24 @@ struct Worker : Nan::AsyncWorker { // query point lng/lat geometry.hpp point (used for distance calculation later on) mapbox::geometry::point query_lnglat{data.longitude, data.latitude}; - // for each tile + gzip::Decompressor decompressor; + std::string uncompressed; + std::vector buffers; + std::vector> tiles; + tiles.reserve(data.tiles.size()); for (auto const& tile_ptr : data.tiles) { TileObject const& tile_obj = *tile_ptr; - vtzero::vector_tile tile{tile_obj.data}; - + if (gzip::is_compressed(tile_obj.data.data(), tile_obj.data.size())) { + decompressor.decompress(uncompressed, tile_obj.data.data(), tile_obj.data.size()); + buffers.emplace_back(std::move(uncompressed)); + tiles.emplace_back(vtzero::vector_tile(buffers.back()), tile_obj.z, tile_obj.x, tile_obj.y); + } else { + tiles.emplace_back(vtzero::vector_tile(tile_obj.data), tile_obj.z, tile_obj.x, tile_obj.y); + } + } + // for each tile + for (auto& tile_obj : tiles) { + vtzero::vector_tile& tile = std::get<0>(tile_obj); while (auto layer = tile.next_layer()) { // check if this is a layer we should query @@ -282,8 +299,11 @@ struct Worker : Nan::AsyncWorker { } std::uint32_t extent = layer.extent(); + std::int32_t tile_obj_z = std::get<1>(tile_obj); + std::int32_t tile_obj_x = std::get<2>(tile_obj); + std::int32_t tile_obj_y = std::get<3>(tile_obj); // query point in relation to the current tile the layer extent - mapbox::geometry::point query_point = utils::create_query_point(data.longitude, data.latitude, extent, tile_obj.z, tile_obj.x, tile_obj.y); + mapbox::geometry::point query_point = utils::create_query_point(data.longitude, data.latitude, extent, tile_obj_z, tile_obj_x, tile_obj_y); while (auto feature = layer.next_feature()) { auto original_geometry_type = get_geometry_type(feature); @@ -306,7 +326,7 @@ struct Worker : Nan::AsyncWorker { // if distance from the query point is greater than 0.0 (not a direct hit) so recalculate the latlng if (cp_info.distance > 0.0) { - ll = utils::convert_vt_to_ll(extent, tile_obj.z, tile_obj.x, tile_obj.y, cp_info); + ll = utils::convert_vt_to_ll(extent, tile_obj_z, tile_obj_x, tile_obj_y, cp_info); meters = utils::distance_in_meters(query_lnglat, ll); } @@ -352,6 +372,16 @@ struct Worker : Nan::AsyncWorker { } // end tile.layer.feature loop } // end tile.layer loop } // end tile loop + // Here we create "materialized" properties. We do this here because, when reading from a compressed + // buffer, it is unsafe to touch `feature.properties_vector` once we've left this loop. + // That is because the buffer may represent uncompressed data that is not in scope outside of Execute() + for (auto& feature : results_queue_) { + feature.properties_vector_materialized.reserve(feature.properties_vector.size()); + for (auto const& property : feature.properties_vector) { + auto val = vtzero::convert_property_value(property.value()); + feature.properties_vector_materialized.emplace_back(std::string(property.key()), std::move(val)); + } + } } catch (const std::exception& e) { SetErrorMessage(e.what()); } @@ -384,7 +414,7 @@ struct Worker : Nan::AsyncWorker { // create properties object v8::Local properties_obj = Nan::New(); - for (auto const& prop : feature.properties_vector) { + for (auto const& prop : feature.properties_vector_materialized) { set_property(prop, properties_obj); } From ee1bd3dc535b597786ef06545abec5c998b7c91d Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 26 Jun 2018 16:30:43 -0700 Subject: [PATCH 2/3] clang-format fixes --- src/vtquery.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vtquery.cpp b/src/vtquery.cpp index 1da79aca..526d3884 100644 --- a/src/vtquery.cpp +++ b/src/vtquery.cpp @@ -3,6 +3,8 @@ #include #include +#include +#include #include #include #include @@ -15,8 +17,6 @@ #include #include #include -#include -#include namespace VectorTileQuery { From f98b2b65b8374ef01bacf8bca96867d088d46ac4 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 27 Jun 2018 10:50:16 -0700 Subject: [PATCH 3/3] use consistent const& style --- src/vtquery.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vtquery.cpp b/src/vtquery.cpp index 526d3884..ee6071ac 100644 --- a/src/vtquery.cpp +++ b/src/vtquery.cpp @@ -382,7 +382,7 @@ struct Worker : Nan::AsyncWorker { feature.properties_vector_materialized.emplace_back(std::string(property.key()), std::move(val)); } } - } catch (const std::exception& e) { + } catch (std::exception const& e) { SetErrorMessage(e.what()); } }