Skip to content

Commit

Permalink
fail on reportGeometryValidity - [WIP]
Browse files Browse the repository at this point in the history
  • Loading branch information
mapsam committed Mar 11, 2016
1 parent 56ceb37 commit a83d2d7
Show file tree
Hide file tree
Showing 5 changed files with 13,713 additions and 2 deletions.
49 changes: 48 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,15 @@ function Bridge(uri, callback) {
return callback && callback(new Error('No xml'));
}

if (uri.throwOnInvalid) source._throw = uri.throwOnInvalid;

source._uri = uri;
source._base = path.resolve(uri.base || __dirname);

// 'blank' option forces all solid tiles to be interpreted as blank.
source._blank = typeof uri.blank === 'boolean' ? uri.blank : false;

if (callback) source.once('open', callback);

source.update(uri, function(err) {
source.emit('open', err, source);
});
Expand Down Expand Up @@ -277,10 +278,24 @@ Bridge.getVector = function(source, map, z, x, y, callback) {
if (err) {
return callback(err);
}

// check geometry validtiy, throw error if invalid
if (source._throw) {
vtile.reportGeometryValidity(function(err, valid) {
if (err) return callback(err);
if (valid.length) {
var validFailures = parseValidityFailures(valid);
return callback(null, validFailures);
}
else return callback();
});
}

headers['x-tilelive-contains-data'] = vtile.painted();
if (vtile.empty()) {
return callback(new Error('Tile does not exist'), null, headers);
}

vtile.getData({compression:'gzip'}, function(err, pbfz) {
if (err) return callback(err);
headers['Content-Encoding'] = 'gzip';
Expand All @@ -289,6 +304,38 @@ Bridge.getVector = function(source, map, z, x, y, callback) {
});
};

function parseValidityFailures(failures) {
var failCodes = failures.reduce(function(a, b) {
var failCode = invalidStrings[b.message.split('.')[0]] || 'ERR UNEXPECTED REASON';
if (failCode === 'self_intersections') {
var matchCode = /method\:\s([a-z\-\?\!])/.exec(b.message);
if (matchCode.length) failCode += '_method_' + matchCode[1];
}

if (!a[b.layer]) a[b.layer] = {};
if (!a[b.layer][b.featureId]) a[b.layer][b.featureId] = {'validity_failures': {}};
if (!a[b.layer][b.featureId][failCode]) a[b.layer][b.featureId]['validity_failures'][failCode] = 1;
else a[b.layer][b.featureId]['validity_failures'][failCode]++;
return a;
}, {});
return failCodes;
}
var invalidStrings = {
'Geometry is valid' : 'no_failure',
'Geometry has too few points' : 'few_points',
'Geometry has wrong topological dimension' : 'wrong_topological_dimension',
'Geometry is defined as closed but is open' : 'not_closed',
'Geometry has spikes' : 'spikes',
'Geometry has invalid self-intersections' : 'self_intersections',
'Geometry has wrong orientation' : 'wrong_orientation',
'Geometry has interior rings defined outside the outer boundary' : 'interior_rings_outside',
'Geometry has nested interior rings' : 'nested_interior_rings',
'Geometry has disconnected interior' : 'disconnected_interior',
'Multi-polygon has intersecting interiors' : 'intersecting_interiors',
'Geometry has duplicate (consecutive) points' : 'duplicate_points',
'Box has corners in wrong order' : 'wrong_corner_order'
};

Bridge.prototype.getInfo = function(callback) {
var map = this._readonly_map;
if (!map) {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
}
],
"dependencies": {
"mapnik": "~3.5.0",
"mapnik": "git://github.com/mapnik/node-mapnik.git#fa0bcfebc76efe6471508eb9d838a142f4e379b2",
"sphericalmercator": "1.0.x",
"mapnik-pool": "~0.1.3"
},
Expand Down
12 changes: 12 additions & 0 deletions test/bench-vector.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,18 @@ tape('vector bench deferred', function(assert) {
});
});

tape.only('throw on invalid geometry', function(assert) {
new Bridge({ xml: fs.readFileSync(path.resolve(path.join(__dirname,'/tile-boundary-test.xml')), 'utf8'), base:path.join(__dirname,'/'), throwOnInvalid: true }, function(err, s) {
// should return on invalid tile using reportGeometryValidity()
s.getTile(15, 19470, 17537, function(err, data) {
// if (err) throw err;
console.log('err', err);
console.log('data', data);
});
assert.end();
});
});

// Currently there is a bug in std::future in xcode that will be fixed in 7.3 release
// until that point the binaries built in OSX could possibly cause memory corruption
// when using non deferred processing (like a terrorist) when that is fixed this can be removed.
Expand Down

0 comments on commit a83d2d7

Please sign in to comment.