[Pkg-javascript-commits] [node-mapnik] 01/17: Imported Upstream version 3.5.12+dfsg
Sebastiaan Couwenberg
sebastic at moszumanska.debian.org
Tue May 10 18:16:02 UTC 2016
This is an automated email from the git hooks/post-receive script.
sebastic pushed a commit to branch master
in repository node-mapnik.
commit 731962904619c12c3431a76d536432aab8d97f41
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date: Sun May 8 23:17:17 2016 +0200
Imported Upstream version 3.5.12+dfsg
---
.travis.yml | 35 ++-
CHANGELOG.md | 19 ++
deps/clipper/clipper.cpp | 22 +-
package.json | 4 +-
scripts/build-appveyor.bat | 1 -
scripts/is_pr_merge.sh | 27 +++
scripts/publish.sh | 26 ++
src/mapnik_vector_tile.cpp | 269 ++++++++++++++++-----
test/data/vector_tile/compositing/25084.vector.pbf | Bin 0 -> 10847 bytes
.../vector_tile/compositing/25084_2.vector.pbf | Bin 0 -> 4623 bytes
.../vector_tile/compositing/expected/2-1-1b.png | Bin 154578 -> 154481 bytes
.../expected/world-reencode-max-extent.png | Bin 7991 -> 7991 bytes
.../compositing/expected/world-reencode.png | Bin 7984 -> 7983 bytes
test/vector-tile.composite.test.js | 16 ++
test/vector-tile.test.js | 34 ++-
15 files changed, 366 insertions(+), 87 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 9c39f88..8c14ed3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -31,37 +31,37 @@ matrix:
- os: osx
osx_image: xcode7
compiler: clang
- env: NODE_VERSION="4" COVERAGE=true NPM_FLAGS="--debug" # node abi 46
+ env: NODE_VERSION="4" COVERAGE=true NPM_FLAGS="--debug" PUBLISHABLE=false # node abi 46
# Linux
- os: linux
compiler: clang
- env: NODE_VERSION="5" # node abi 47
+ env: NODE_VERSION="5" PUBLISHABLE=true # node abi 47
- os: linux
compiler: clang
- env: NODE_VERSION="4" # node abi 46
+ env: NODE_VERSION="4" PUBLISHABLE=true # node abi 46
- os: linux
compiler: clang
- env: NODE_VERSION="0.10" NPM_FLAGS="--debug" # node abi 11
+ env: NODE_VERSION="0.10" NPM_FLAGS="--debug" PUBLISHABLE=true # node abi 11
- os: linux
compiler: clang
- env: NODE_VERSION="0.10" # node abi 11
+ env: NODE_VERSION="0.10" PUBLISHABLE=true # node abi 11
# OS X
- os: osx
osx_image: xcode7
compiler: clang
- env: NODE_VERSION="5" # node abi 47
+ env: NODE_VERSION="5" PUBLISHABLE=true # node abi 47
- os: osx
osx_image: xcode7
compiler: clang
- env: NODE_VERSION="4" # node abi 46
+ env: NODE_VERSION="4" PUBLISHABLE=true # node abi 46
- os: osx
osx_image: xcode7
compiler: clang
- env: NODE_VERSION="0.10" NPM_FLAGS="--debug" # node abi 11
+ env: NODE_VERSION="0.10" NPM_FLAGS="--debug" PUBLISHABLE=true # node abi 11
- os: osx
osx_image: xcode7
compiler: clang
- env: NODE_VERSION="0.10" # node abi 11
+ env: NODE_VERSION="0.10" PUBLISHABLE=true # node abi 11
before_install:
- scripts/validate_tag.sh
@@ -93,19 +93,16 @@ install:
- npm test
before_script:
- - if [[ ${COVERAGE} == false ]]; then
- echo "publishing";
- if [[ ${COMMIT_MESSAGE} =~ "[publish binary]" ]]; then
- echo "publishing for the first time";
- node-pre-gyp publish ${NPM_FLAGS};
- elif [[ ${COMMIT_MESSAGE} =~ "[republish binary]" ]]; then
- echo "republishing";
- node-pre-gyp unpublish publish ${NPM_FLAGS};
- fi
- fi
+- if [[ ${PUBLISHABLE} == true ]]; then
+ ./scripts/publish.sh;
+ fi;
script:
- if [[ ${COVERAGE} == true ]]; then ./mason_packages/.link/bin/cpp-coveralls --exclude __nvm --exclude node_modules --exclude tests --build-root build --gcov-options '\-lp' --exclude tools --exclude docs --exclude sdk --exclude build/Debug/obj/gen --exclude build/Release/obj/gen --exclude src/mapnik_featureset.hpp --exclude src/mapnik_logger.hpp --exclude src/mapnik_image_view.hpp --exclude src/mapnik_geometry.hpp --exclude deps > /dev/null; fi;
#- node --expose-gc bench/error/test_vt_abort2.js
# ugh: always killed by travis
#- nice -n 19 node --expose-gc bench/error/test_vt_abort.js
+
+notifications:
+ slack:
+ secure: wLpScQaDoEsVe0Bu28b62FGZBfmX3s/NK8DWcuSxEFx80k8RKPNgnMg8htamG0zRSf5htF+X6jy2P0IeUvbeupIaJwqtXvHaJYtlMTmemG/xuXLTpLp6k6giT2mWm/lp+ykuaF/PvUcZWUhSf1zhS6vwIekrMYIcDYvNXjO8DNw=
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 49d1642..c695f26 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,24 @@
# Changelog
+## 3.5.12
+
+- Fix performance regression when passing raster through vector tile (via upgrade to mapnik-vector-tile at 1.1.2)
+
+## 3.5.11
+
+- Fix for numerical precision issue in mapnik vector tile where valid v2 vector tiles would be thrown as invalid
+- Added new exception handling for toGeoJSON
+
+## 3.5.10
+
+- Fix for a segfault in the vector tile clipping library
+
+## 3.5.9
+
+- Updated to mapnik-vector-tile `1.1.0`
+- Automatic updating of vector tiles from v1 to v2 no longer takes place automatically when using `setData` and `addData`.
+- Validation of vector tiles is now optional when using `setData` and `addData`
+
## 3.5.8
- Updated to mapnik-vector-tile `1.0.6` which includes a speedup on simplification for mapnik-vector-tile
diff --git a/deps/clipper/clipper.cpp b/deps/clipper/clipper.cpp
index 3c1f3f0..2cd7102 100644
--- a/deps/clipper/clipper.cpp
+++ b/deps/clipper/clipper.cpp
@@ -3986,11 +3986,27 @@ void Clipper::FixupFirstLefts2(OutRec* InnerOutRec, OutRec* OuterOutRec)
{
if (outRec->IsHole == OuterOutRec->IsHole)
{
- outRec->FirstLeft = ParseFirstLeft(OuterOutRec->FirstLeft);
+ if (Poly2ContainsPoly1(outRec->Pts, OuterOutRec->Pts))
+ {
+ outRec->FirstLeft = OuterOutRec;
+ }
+ else
+ {
+ outRec->FirstLeft = ParseFirstLeft(OuterOutRec->FirstLeft);
+ }
}
else
{
- outRec->FirstLeft = OuterOutRec;
+ if (Area(outRec->Pts) == 0.0 && !Poly2ContainsPoly1(outRec->Pts, OuterOutRec->Pts))
+ {
+ outRec->IsHole = !outRec->IsHole;
+ outRec->FirstLeft = ParseFirstLeft(OuterOutRec->FirstLeft);
+ ReversePolyPtLinks(outRec->Pts);
+ }
+ else
+ {
+ outRec->FirstLeft = OuterOutRec;
+ }
}
}
}
@@ -5215,6 +5231,8 @@ void Clipper::DoSimplePolygons()
dupeRec.emplace(outrec2->Idx, intPt2);
}
}
+ outRec_j = GetOutRec(m_OutPts[j]->Idx);
+ idx_j = outRec_j->Idx;
}
continue;
}
diff --git a/package.json b/package.json
index ed58fd4..e98b9e5 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,7 @@
"url": "http://github.com/mapnik/node-mapnik",
"homepage": "http://mapnik.org",
"author": "Dane Springmeyer <dane at mapbox.com> (mapnik.org)",
- "version": "3.5.8",
+ "version": "3.5.12",
"mapnik_version":"3.0.11",
"main": "./lib/mapnik.js",
"binary": {
@@ -41,7 +41,7 @@
}
],
"dependencies": {
- "mapnik-vector-tile": "1.0.6",
+ "mapnik-vector-tile": "1.1.2",
"nan": "~2.2.0",
"node-pre-gyp": "~0.6.25",
"protozero": "~1.3.0"
diff --git a/scripts/build-appveyor.bat b/scripts/build-appveyor.bat
index f4695db..6f7916e 100644
--- a/scripts/build-appveyor.bat
+++ b/scripts/build-appveyor.bat
@@ -146,7 +146,6 @@ IF %ERRORLEVEL% NEQ 0 GOTO ERROR
CALL npm test
:: uncomment to allow build to work even if tests do not pass
-::SET ERRORLEVEL=0
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
ECHO APPVEYOR_REPO_COMMIT_MESSAGE^: %APPVEYOR_REPO_COMMIT_MESSAGE%
diff --git a/scripts/is_pr_merge.sh b/scripts/is_pr_merge.sh
new file mode 100755
index 0000000..6e94c1a
--- /dev/null
+++ b/scripts/is_pr_merge.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+set -eu pipefail
+
+: '
+
+This script is designed to detect if a gitsha represents a normal
+push commit (to any branch) or whether it represents travis attempting
+to merge between the origin and the upstream branch.
+
+For more details see: https://docs.travis-ci.com/user/pull-requests
+
+'
+
+# Get the commit message via git log
+# This should always be the exact text the developer provided
+COMMIT_LOG=$(git log --format=%B --no-merges -n 1 | tr -d '\n')
+
+# Get the commit message via git show
+# If the gitsha represents a merge then this will
+# look something like "Merge e3b1981 into 615d2a3"
+# Otherwise it will be the same as the "git log" output
+COMMIT_SHOW=$(git show -s --format=%B | tr -d '\n')
+
+if [[ "${COMMIT_LOG}" != "${COMMIT_SHOW}" ]]; then
+ echo true
+fi
diff --git a/scripts/publish.sh b/scripts/publish.sh
new file mode 100755
index 0000000..a8f4d43
--- /dev/null
+++ b/scripts/publish.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+echo "dumping binary meta..."
+./node_modules/.bin/node-pre-gyp reveal ${NPM_FLAGS}
+
+echo "determining publishing status..."
+
+if [[ $(./scripts/is_pr_merge.sh) ]]; then
+ echo "Skipping publishing because this is a PR merge commit"
+else
+ echo "This is a push commit, continuing to package..."
+ ./node_modules/.bin/node-pre-gyp package ${NPM_FLAGS}
+
+ COMMIT_MESSAGE=$(git log --format=%B --no-merges | head -n 1 | tr -d '\n')
+ echo "Commit message: ${COMMIT_MESSAGE}"
+
+ if [[ ${COMMIT_MESSAGE} =~ "[publish binary]" ]]; then
+ echo "Publishing"
+ ./node_modules/.bin/node-pre-gyp publish ${NPM_FLAGS}
+ elif [[ ${COMMIT_MESSAGE} =~ "[republish binary]" ]]; then
+ echo "Re-Publishing"
+ ./node_modules/.bin/node-pre-gyp unpublish publish ${NPM_FLAGS}
+ else
+ echo "Skipping publishing"
+ fi;
+fi
diff --git a/src/mapnik_vector_tile.cpp b/src/mapnik_vector_tile.cpp
index 1e6efea..66cf466 100644
--- a/src/mapnik_vector_tile.cpp
+++ b/src/mapnik_vector_tile.cpp
@@ -466,6 +466,10 @@ void _composite(VectorTile* target_vt,
{
map.set_maximum_extent(*max_extent);
}
+ else
+ {
+ map.set_maximum_extent(target_vt->get_tile()->get_buffered_extent());
+ }
std::vector<mapnik::vector_tile_impl::merc_tile_ptr> merc_vtiles;
for (VectorTile* vt : vtiles)
@@ -2922,47 +2926,57 @@ v8::Local<v8::Value> VectorTile::_toGeoJSONSync(Nan::NAN_METHOD_ARGS_TYPE info)
VectorTile* v = Nan::ObjectWrap::Unwrap<VectorTile>(info.Holder());
std::string result;
- if (layer_id->IsString())
+ try
{
- std::string layer_name = TOSTR(layer_id);
- if (layer_name == "__array__")
- {
- write_geojson_array(result, v);
- }
- else if (layer_name == "__all__")
+ if (layer_id->IsString())
{
- write_geojson_all(result, v);
+ std::string layer_name = TOSTR(layer_id);
+ if (layer_name == "__array__")
+ {
+ write_geojson_array(result, v);
+ }
+ else if (layer_name == "__all__")
+ {
+ write_geojson_all(result, v);
+ }
+ else
+ {
+ if (!write_geojson_layer_name(result, layer_name, v))
+ {
+ std::string error_msg("Layer name '" + layer_name + "' not found");
+ Nan::ThrowTypeError(error_msg.c_str());
+ return scope.Escape(Nan::Undefined());
+ }
+ }
}
- else
+ else if (layer_id->IsNumber())
{
- if (!write_geojson_layer_name(result, layer_name, v))
+ int layer_idx = layer_id->IntegerValue();
+ if (layer_idx < 0)
{
- std::string error_msg("Layer name '" + layer_name + "' not found");
- Nan::ThrowTypeError(error_msg.c_str());
+ Nan::ThrowTypeError("A layer index can not be negative");
+ return scope.Escape(Nan::Undefined());
+ }
+ else if (layer_idx >= static_cast<int>(v->get_tile()->get_layers().size()))
+ {
+ Nan::ThrowTypeError("Layer index exceeds the number of layers in the vector tile.");
+ return scope.Escape(Nan::Undefined());
+ }
+ if (!write_geojson_layer_index(result, layer_idx, v))
+ {
+ // LCOV_EXCL_START
+ Nan::ThrowTypeError("Layer could not be retrieved (should have not reached here)");
return scope.Escape(Nan::Undefined());
+ // LCOV_EXCL_STOP
}
}
}
- else if (layer_id->IsNumber())
+ catch (std::exception const& ex)
{
- int layer_idx = layer_id->IntegerValue();
- if (layer_idx < 0)
- {
- Nan::ThrowTypeError("A layer index can not be negative");
- return scope.Escape(Nan::Undefined());
- }
- else if (layer_idx >= static_cast<int>(v->get_tile()->get_layers().size()))
- {
- Nan::ThrowTypeError("Layer index exceeds the number of layers in the vector tile.");
- return scope.Escape(Nan::Undefined());
- }
- if (!write_geojson_layer_index(result, layer_idx, v))
- {
- // LCOV_EXCL_START
- Nan::ThrowTypeError("Layer could not be retrieved (should have not reached here)");
- return scope.Escape(Nan::Undefined());
- // LCOV_EXCL_STOP
- }
+ // LCOV_EXCL_START
+ Nan::ThrowTypeError(ex.what());
+ return scope.Escape(Nan::Undefined());
+ // LCOV_EXCL_STOP
}
return scope.Escape(Nan::New<v8::String>(result).ToLocalChecked());
}
@@ -3816,6 +3830,10 @@ void VectorTile::EIO_AfterAddImageBuffer(uv_work_t* req)
* @instance
* @name addDataSync
* @param {Buffer} buffer - raw data
+ * @param {object} [options]
+ * @param {boolean} [options.validate=false] - If true does validity checks mvt schema (not geometries)
+ * Will throw if anything invalid or unexpected is encountered in the data
+ * @param {boolean} [options.upgrade=false] - If true will upgrade v1 tiles to adhere to the v2 specification
* @example
* var data_buffer = fs.readFileSync('./path/to/data.mvt'); // returns a buffer
* // assumes you have created a vector tile object already
@@ -3848,9 +3866,41 @@ v8::Local<v8::Value> VectorTile::_addDataSync(Nan::NAN_METHOD_ARGS_TYPE info)
Nan::ThrowError("cannot accept empty buffer as protobuf");
return scope.Escape(Nan::Undefined());
}
+ bool upgrade = false;
+ bool validate = false;
+ v8::Local<v8::Object> options = Nan::New<v8::Object>();
+ if (info.Length() > 1)
+ {
+ if (!info[1]->IsObject())
+ {
+ Nan::ThrowTypeError("second arg must be a options object");
+ return scope.Escape(Nan::Undefined());
+ }
+ options = info[1]->ToObject();
+ if (options->Has(Nan::New<v8::String>("validate").ToLocalChecked()))
+ {
+ v8::Local<v8::Value> param_val = options->Get(Nan::New("validate").ToLocalChecked());
+ if (!param_val->IsBoolean())
+ {
+ Nan::ThrowTypeError("option 'validate' must be a boolean");
+ return scope.Escape(Nan::Undefined());
+ }
+ validate = param_val->BooleanValue();
+ }
+ if (options->Has(Nan::New<v8::String>("upgrade").ToLocalChecked()))
+ {
+ v8::Local<v8::Value> param_val = options->Get(Nan::New("upgrade").ToLocalChecked());
+ if (!param_val->IsBoolean())
+ {
+ Nan::ThrowTypeError("option 'upgrade' must be a boolean");
+ return scope.Escape(Nan::Undefined());
+ }
+ upgrade = param_val->BooleanValue();
+ }
+ }
try
{
- merge_from_compressed_buffer(*d->get_tile(), node::Buffer::Data(obj), buffer_size);
+ merge_from_compressed_buffer(*d->get_tile(), node::Buffer::Data(obj), buffer_size, validate, upgrade);
}
catch (std::exception const& ex)
{
@@ -3865,6 +3915,8 @@ typedef struct
uv_work_t request;
VectorTile* d;
const char *data;
+ bool validate;
+ bool upgrade;
size_t dataLength;
bool error;
std::string error_name;
@@ -3880,6 +3932,10 @@ typedef struct
* @instance
* @name addData
* @param {Buffer} buffer - raw vector data
+ * @param {object} [options]
+ * @param {boolean} [options.validate=false] - If true does validity checks mvt schema (not geometries)
+ * Will throw if anything invalid or unexpected is encountered in the data
+ * @param {boolean} [options.upgrade=false] - If true will upgrade v1 tiles to adhere to the v2 specification
* @param {Object} callback
* @example
* var data_buffer = fs.readFileSync('./path/to/data.mvt'); // returns a buffer
@@ -3891,17 +3947,11 @@ typedef struct
*/
NAN_METHOD(VectorTile::addData)
{
- if (info.Length() == 1)
- {
- info.GetReturnValue().Set(_addDataSync(info));
- return;
- }
-
// ensure callback is a function
v8::Local<v8::Value> callback = info[info.Length() - 1];
if (!info[info.Length() - 1]->IsFunction())
{
- Nan::ThrowTypeError("last argument must be a callback function");
+ info.GetReturnValue().Set(_addDataSync(info));
return;
}
@@ -3917,11 +3967,46 @@ NAN_METHOD(VectorTile::addData)
return;
}
+ bool upgrade = false;
+ bool validate = false;
+ v8::Local<v8::Object> options = Nan::New<v8::Object>();
+ if (info.Length() > 1)
+ {
+ if (!info[1]->IsObject())
+ {
+ Nan::ThrowTypeError("second arg must be a options object");
+ return;
+ }
+ options = info[1]->ToObject();
+ if (options->Has(Nan::New<v8::String>("validate").ToLocalChecked()))
+ {
+ v8::Local<v8::Value> param_val = options->Get(Nan::New("validate").ToLocalChecked());
+ if (!param_val->IsBoolean())
+ {
+ Nan::ThrowTypeError("option 'validate' must be a boolean");
+ return;
+ }
+ validate = param_val->BooleanValue();
+ }
+ if (options->Has(Nan::New<v8::String>("upgrade").ToLocalChecked()))
+ {
+ v8::Local<v8::Value> param_val = options->Get(Nan::New("upgrade").ToLocalChecked());
+ if (!param_val->IsBoolean())
+ {
+ Nan::ThrowTypeError("option 'upgrade' must be a boolean");
+ return;
+ }
+ upgrade = param_val->BooleanValue();
+ }
+ }
+
VectorTile* d = Nan::ObjectWrap::Unwrap<VectorTile>(info.Holder());
vector_tile_adddata_baton_t *closure = new vector_tile_adddata_baton_t();
closure->request.data = closure;
closure->d = d;
+ closure->validate = validate;
+ closure->upgrade = upgrade;
closure->error = false;
closure->cb.Reset(callback.As<v8::Function>());
closure->buffer.Reset(obj.As<v8::Object>());
@@ -3944,7 +4029,7 @@ void VectorTile::EIO_AddData(uv_work_t* req)
}
try
{
- merge_from_compressed_buffer(*closure->d->get_tile(), closure->data, closure->dataLength);
+ merge_from_compressed_buffer(*closure->d->get_tile(), closure->data, closure->dataLength, closure->validate, closure->upgrade);
}
catch (std::exception const& ex)
{
@@ -3982,6 +4067,10 @@ void VectorTile::EIO_AfterAddData(uv_work_t* req)
* @instance
* @name setDataSync
* @param {Buffer} buffer - raw data
+ * @param {object} [options]
+ * @param {boolean} [options.validate=false] - If true does validity checks mvt schema (not geometries)
+ * Will throw if anything invalid or unexpected is encountered in the data
+ * @param {boolean} [options.upgrade=false] - If true will upgrade v1 tiles to adhere to the v2 specification
* @example
* var data = fs.readFileSync('./path/to/data.mvt');
* vectorTile.setDataSync(data);
@@ -4013,10 +4102,42 @@ v8::Local<v8::Value> VectorTile::_setDataSync(Nan::NAN_METHOD_ARGS_TYPE info)
Nan::ThrowError("cannot accept empty buffer as protobuf");
return scope.Escape(Nan::Undefined());
}
+ bool upgrade = false;
+ bool validate = false;
+ v8::Local<v8::Object> options = Nan::New<v8::Object>();
+ if (info.Length() > 1)
+ {
+ if (!info[1]->IsObject())
+ {
+ Nan::ThrowTypeError("second arg must be a options object");
+ return scope.Escape(Nan::Undefined());
+ }
+ options = info[1]->ToObject();
+ if (options->Has(Nan::New<v8::String>("validate").ToLocalChecked()))
+ {
+ v8::Local<v8::Value> param_val = options->Get(Nan::New("validate").ToLocalChecked());
+ if (!param_val->IsBoolean())
+ {
+ Nan::ThrowTypeError("option 'validate' must be a boolean");
+ return scope.Escape(Nan::Undefined());
+ }
+ validate = param_val->BooleanValue();
+ }
+ if (options->Has(Nan::New<v8::String>("upgrade").ToLocalChecked()))
+ {
+ v8::Local<v8::Value> param_val = options->Get(Nan::New("upgrade").ToLocalChecked());
+ if (!param_val->IsBoolean())
+ {
+ Nan::ThrowTypeError("option 'upgrade' must be a boolean");
+ return scope.Escape(Nan::Undefined());
+ }
+ upgrade = param_val->BooleanValue();
+ }
+ }
try
{
d->clear();
- merge_from_compressed_buffer(*d->get_tile(), node::Buffer::Data(obj), buffer_size);
+ merge_from_compressed_buffer(*d->get_tile(), node::Buffer::Data(obj), buffer_size, validate, upgrade);
}
catch (std::exception const& ex)
{
@@ -4031,6 +4152,8 @@ typedef struct
uv_work_t request;
VectorTile* d;
const char *data;
+ bool validate;
+ bool upgrade;
size_t dataLength;
bool error;
std::string error_name;
@@ -4046,6 +4169,10 @@ typedef struct
* @instance
* @name setData
* @param {Buffer} buffer - raw data
+ * @param {object} [options]
+ * @param {boolean} [options.validate=false] - If true does validity checks mvt schema (not geometries)
+ * Will throw if anything invalid or unexpected is encountered in the data
+ * @param {boolean} [options.upgrade=false] - If true will upgrade v1 tiles to adhere to the v2 specification
* @param {Function} callback
* @example
* var data = fs.readFileSync('./path/to/data.mvt');
@@ -4056,17 +4183,11 @@ typedef struct
*/
NAN_METHOD(VectorTile::setData)
{
- if (info.Length() == 1)
- {
- info.GetReturnValue().Set(_setDataSync(info));
- return;
- }
-
// ensure callback is a function
v8::Local<v8::Value> callback = info[info.Length() - 1];
if (!info[info.Length() - 1]->IsFunction())
{
- Nan::ThrowTypeError("last argument must be a callback function");
+ info.GetReturnValue().Set(_setDataSync(info));
return;
}
@@ -4082,10 +4203,45 @@ NAN_METHOD(VectorTile::setData)
return;
}
+ bool upgrade = false;
+ bool validate = false;
+ v8::Local<v8::Object> options = Nan::New<v8::Object>();
+ if (info.Length() > 1)
+ {
+ if (!info[1]->IsObject())
+ {
+ Nan::ThrowTypeError("second arg must be a options object");
+ return;
+ }
+ options = info[1]->ToObject();
+ if (options->Has(Nan::New<v8::String>("validate").ToLocalChecked()))
+ {
+ v8::Local<v8::Value> param_val = options->Get(Nan::New("validate").ToLocalChecked());
+ if (!param_val->IsBoolean())
+ {
+ Nan::ThrowTypeError("option 'validate' must be a boolean");
+ return;
+ }
+ validate = param_val->BooleanValue();
+ }
+ if (options->Has(Nan::New<v8::String>("upgrade").ToLocalChecked()))
+ {
+ v8::Local<v8::Value> param_val = options->Get(Nan::New("upgrade").ToLocalChecked());
+ if (!param_val->IsBoolean())
+ {
+ Nan::ThrowTypeError("option 'upgrade' must be a boolean");
+ return;
+ }
+ upgrade = param_val->BooleanValue();
+ }
+ }
+
VectorTile* d = Nan::ObjectWrap::Unwrap<VectorTile>(info.Holder());
vector_tile_setdata_baton_t *closure = new vector_tile_setdata_baton_t();
closure->request.data = closure;
+ closure->validate = validate;
+ closure->upgrade = upgrade;
closure->d = d;
closure->error = false;
closure->cb.Reset(callback.As<v8::Function>());
@@ -4111,7 +4267,7 @@ void VectorTile::EIO_SetData(uv_work_t* req)
try
{
closure->d->clear();
- merge_from_compressed_buffer(*closure->d->get_tile(), closure->data, closure->dataLength);
+ merge_from_compressed_buffer(*closure->d->get_tile(), closure->data, closure->dataLength, closure->validate, closure->upgrade);
}
catch (std::exception const& ex)
{
@@ -6380,19 +6536,24 @@ NAN_METHOD(VectorTile::info)
case mapnik::vector_tile_impl::Tile_Encoding::LAYERS:
{
v8::Local<v8::Object> layer_obj = Nan::New<v8::Object>();
- protozero::pbf_reader layer_msg = tile_msg.get_message();
std::uint64_t point_feature_count = 0;
std::uint64_t line_feature_count = 0;
std::uint64_t polygon_feature_count = 0;
std::uint64_t unknown_feature_count = 0;
std::uint64_t raster_feature_count = 0;
- std::string layer_name;
- std::uint32_t layer_version = 1;
+ auto layer_data = tile_msg.get_data();
+ protozero::pbf_reader layer_props_msg(layer_data);
+ auto layer_info = mapnik::vector_tile_impl::get_layer_name_and_version(layer_props_msg);
+ std::string const& layer_name = layer_info.first;
+ std::uint32_t layer_version = layer_info.second;
std::set<mapnik::vector_tile_impl::validity_error> layer_errors;
+ if (version > 2 || version < 1)
+ {
+ layer_errors.insert(mapnik::vector_tile_impl::LAYER_HAS_UNSUPPORTED_VERSION);
+ }
+ protozero::pbf_reader layer_msg(layer_data);
mapnik::vector_tile_impl::layer_is_valid(layer_msg,
layer_errors,
- layer_name,
- layer_version,
point_feature_count,
line_feature_count,
polygon_feature_count,
diff --git a/test/data/vector_tile/compositing/25084.vector.pbf b/test/data/vector_tile/compositing/25084.vector.pbf
new file mode 100644
index 0000000..7403c2b
Binary files /dev/null and b/test/data/vector_tile/compositing/25084.vector.pbf differ
diff --git a/test/data/vector_tile/compositing/25084_2.vector.pbf b/test/data/vector_tile/compositing/25084_2.vector.pbf
new file mode 100644
index 0000000..d2bd8e8
Binary files /dev/null and b/test/data/vector_tile/compositing/25084_2.vector.pbf differ
diff --git a/test/data/vector_tile/compositing/expected/2-1-1b.png b/test/data/vector_tile/compositing/expected/2-1-1b.png
index 04b020e..f06feac 100644
Binary files a/test/data/vector_tile/compositing/expected/2-1-1b.png and b/test/data/vector_tile/compositing/expected/2-1-1b.png differ
diff --git a/test/data/vector_tile/compositing/expected/world-reencode-max-extent.png b/test/data/vector_tile/compositing/expected/world-reencode-max-extent.png
index fa9dc7d..d78b900 100644
Binary files a/test/data/vector_tile/compositing/expected/world-reencode-max-extent.png and b/test/data/vector_tile/compositing/expected/world-reencode-max-extent.png differ
diff --git a/test/data/vector_tile/compositing/expected/world-reencode.png b/test/data/vector_tile/compositing/expected/world-reencode.png
index 63d727c..b1e913f 100644
Binary files a/test/data/vector_tile/compositing/expected/world-reencode.png and b/test/data/vector_tile/compositing/expected/world-reencode.png differ
diff --git a/test/vector-tile.composite.test.js b/test/vector-tile.composite.test.js
index 8debd8c..c0b0512 100644
--- a/test/vector-tile.composite.test.js
+++ b/test/vector-tile.composite.test.js
@@ -784,4 +784,20 @@ describe('mapnik.VectorTile.composite', function() {
done();
});
+ it('should correctly composite -- numerical precision issue in mapnik vector tile area calculation', function() {
+ // Original data.
+ var vt = new mapnik.VectorTile(16,10691,25084);
+ var vt_data = fs.readFileSync('./test/data/vector_tile/compositing/25084.vector.pbf');
+ var vt2 = new mapnik.VectorTile(16,10691,25084);
+ var vt_data2 = fs.readFileSync('./test/data/vector_tile/compositing/25084_2.vector.pbf');
+ vt.setData(vt_data);
+ // Tile data
+ var vtile = new mapnik.VectorTile(18,42764,100336, {buffer_size: 255*16});
+ vtile.composite([vt, vt2]);
+ assert(!vtile.empty());
+ assert.doesNotThrow(function() {
+ vtile.toGeoJSON('wildoak');
+ });
+ });
+
});
diff --git a/test/vector-tile.test.js b/test/vector-tile.test.js
index d620772..f28ec3b 100644
--- a/test/vector-tile.test.js
+++ b/test/vector-tile.test.js
@@ -1330,17 +1330,26 @@ describe('mapnik.VectorTile ', function() {
assert.throws(function() { vtile.setData({},function(){}); }); // first arg must be a buffer object
assert.throws(function() { vtile.setData(new Buffer('foo'), null); });
assert.throws(function() { vtile.setData(new Buffer(0)); }); // empty buffer is not valid
-
- // invalid .mvt
- var badTile = fs.readFileSync(path.resolve(__dirname + '/data/vector_tile/invalid_v2_tile.mvt'));
- assert.throws(function() { vtile.setData(badTile); });
-
vtile.setData(new Buffer('foo'),function(err) {
assert.throws(function() { if (err) throw err; });
done();
});
});
+ it('should error out if we validate tile with empty layers and features to setData - 1', function(done) {
+ var vtile = new mapnik.VectorTile(0,0,0);
+ var tile_with_emptyness = fs.readFileSync(path.resolve(__dirname + '/data/vector_tile/invalid_v2_tile.mvt'));
+ assert.throws(function() { vtile.setData(tile_with_emptyness,{validate:true}); });
+ // tile will be partially parsed (when not upgrading) before validation error is throw
+ // so we check that not all the layers are added
+ assert.equal(vtile.names().length,3);
+ // only fails with validation
+ var vtile3 = new mapnik.VectorTile(0,0,0);
+ vtile3.setData(tile_with_emptyness,{validate:false});
+ assert.equal(vtile3.names().length,23);
+ done();
+ });
+
it('should error out if we pass invalid data to setData - 2', function(done) {
var vtile = new mapnik.VectorTile(0,0,0);
assert.equal(vtile.empty(), true);
@@ -1400,12 +1409,19 @@ describe('mapnik.VectorTile ', function() {
});
});
- it('should return empty and have layer name', function() {
+ it('should not return empty and will have layer name', function() {
var vtile = new mapnik.VectorTile(0,0,0);
- // a layer with only a name "layer-name" and no features
- // during v1 to v2 conversion this will be dropped, it is assumed
- // to be v1 because it has no version!
vtile.setData(new Buffer('1A0C0A0A6C617965722D6E616D65', 'hex'));
+ assert.deepEqual(vtile.names(), ['layer-name']);
+ assert.equal(vtile.empty(), false);
+ });
+
+ it('should return empty and have no layer name when upgraded', function() {
+ var vtile = new mapnik.VectorTile(0,0,0);
+ vtile.setData(new Buffer('1A0C0A0A6C617965722D6E616D65', 'hex'),{upgrade:true});
+ // a layer with only a name "layer-name" and no features
+ // during v1 to v2 conversion this will be dropped
+ // note: this tile also lacks a version, but mapnik-vt defaults to assuming v1
assert.deepEqual(vtile.names(), []);
assert.equal(vtile.empty(), true);
});
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/collab-maint/node-mapnik.git
More information about the Pkg-javascript-commits
mailing list