diff --git a/Document.js b/Document.js index 0db5e6f..aeaa685 100644 --- a/Document.js +++ b/Document.js @@ -45,6 +45,7 @@ function Document( source, layer, source_id ){ this.addPostProcessingScript( require('./post/seperable_street_names').post ); this.addPostProcessingScript( require('./post/deduplication') ); this.addPostProcessingScript( require('./post/language_field_trimming') ); + this.addPostProcessingScript( require('./post/popularity') ); // mandatory properties this.setSource( source ); diff --git a/post/popularity.js b/post/popularity.js new file mode 100644 index 0000000..299f0e9 --- /dev/null +++ b/post/popularity.js @@ -0,0 +1,33 @@ +/** + * Minimum popularity post-processing script ensures that every document + * meets a minimum popularity value based on the layer to which it belongs. + * + * For more info see: + * - https://github.com/pelias/openstreetmap/pull/493#issuecomment-503019975 + * - https://github.com/pelias/openstreetmap/blob/master/stream/popularity_mapper.js + */ + +const _ = require('lodash'); + +const MIN_POPULARITY_MAP = { + postalcode: 9000 +}; + +function popularity(doc) { + let minValue = _.get(MIN_POPULARITY_MAP, doc.getLayer()); + + // only apply to layers listed in the mapping above + if (!_.isFinite(minValue)) { return; } + + // avoid setting a popularity of 0 (or less) + if (minValue <= 0) { return; } + + // skip updating records where the current popularity exceeds the minimum + let currentValue = doc.getPopularity(); + if (_.isFinite(currentValue) && currentValue >= minValue) { return; } + + // set the minimum popularity for this layer + doc.setPopularity(minValue); +} + +module.exports = popularity; diff --git a/test/document/post.js b/test/document/post.js index 74b9928..67c53e7 100644 --- a/test/document/post.js +++ b/test/document/post.js @@ -4,7 +4,8 @@ const intersections = require('../../post/intersections'); const seperable_street_names = require('../../post/seperable_street_names').post; const deduplication = require('../../post/deduplication'); const language_field_trimming = require('../../post/language_field_trimming'); -const DEFAULT_SCRIPTS = [intersections, seperable_street_names, deduplication, language_field_trimming ]; +const popularity = require('../../post/popularity'); +const DEFAULT_SCRIPTS = [intersections, seperable_street_names, deduplication, language_field_trimming, popularity]; module.exports.tests = {}; diff --git a/test/post/popularity.js b/test/post/popularity.js new file mode 100644 index 0000000..5547004 --- /dev/null +++ b/test/post/popularity.js @@ -0,0 +1,66 @@ +const Document = require('../../Document'); +const popularity = require('../../post/popularity'); + +module.exports.tests = {}; + +const MIN_POSTCODE_POPULARITY = 9000; +module.exports.tests.postalcode = function (test) { + test('postalcode - empty', function (t) { + var doc = new Document('mysource', 'postalcode', 'myid'); + + popularity(doc); + t.deepEquals(doc.getPopularity(), MIN_POSTCODE_POPULARITY); + + t.end(); + }); + test('postalcode - zero', function (t) { + var doc = new Document('mysource', 'postalcode', 'myid'); + doc.setPopularity(0); + + popularity(doc); + t.deepEquals(doc.getPopularity(), MIN_POSTCODE_POPULARITY); + + t.end(); + }); + test('postalcode - above minimum', function (t) { + var doc = new Document('mysource', 'postalcode', 'myid'); + doc.setPopularity(9999999); + + popularity(doc); + t.deepEquals(doc.getPopularity(), 9999999); + + t.end(); + }); + test('postalcode - below minimum', function (t) { + var doc = new Document('mysource', 'postalcode', 'myid'); + doc.setPopularity(100); + + popularity(doc); + t.deepEquals(doc.getPopularity(), MIN_POSTCODE_POPULARITY); + + t.end(); + }); +}; + +// layers not listed in MIN_POPULARITY_MAP should result in a no-op +module.exports.tests.noop = function (test) { + test('other layers - no-op', function (t) { + var doc = new Document('mysource', 'mylayer', 'myid'); + + popularity(doc); + t.deepEquals(doc.getPopularity(), undefined); + + t.end(); + }); +}; + +module.exports.all = function (tape, common) { + + function test(name, testFunction) { + return tape('post/popularity: ' + name, testFunction); + } + + for (var testCase in module.exports.tests) { + module.exports.tests[testCase](test, common); + } +}; diff --git a/test/run.js b/test/run.js index 8214362..995f2b4 100644 --- a/test/run.js +++ b/test/run.js @@ -26,6 +26,7 @@ var tests = [ require('./post/deduplication.js'), require('./post/seperable_street_names.js'), require('./post/language_field_trimming.js'), + require('./post/popularity.js'), require('./DocumentMapperStream.js'), require('./util/transform.js'), require('./util/valid.js'),