diff options
-rwxr-xr-x | bin/reduceRangeDuplicates.js | 6 | ||||
-rw-r--r-- | lib/withinRange.js | 18 | ||||
-rw-r--r-- | test/withinRange.js | 12 |
3 files changed, 33 insertions, 3 deletions
diff --git a/bin/reduceRangeDuplicates.js b/bin/reduceRangeDuplicates.js index 4ef57f9..d22d5f2 100755 --- a/bin/reduceRangeDuplicates.js +++ b/bin/reduceRangeDuplicates.js @@ -287,11 +287,12 @@ const reduceNonRange = new Transform({ ].join('/') let dropFeature = false + let dropReason if (key in rangesByStreet) { for (let i = 0; i < rangesByStreet[key].length; i++) { const range = rangesByStreet[key][i] // if the range wasn't just removed in filter A, and the feature is within the range - if (!(hash(range) in rangesRemovedInFilterA) && withinRange(feature, range)) { + if (!(hash(range) in rangesRemovedInFilterA) && withinRange(feature, range, { matchParity: true })) { // found within a range, drop feature unless would drop addr:unit or addr:flats information if ('addr:unit' in feature.properties || 'addr:flats' in feature.properties) { // safe to drop if the same addr:unit and addr:flats is also on the range @@ -299,6 +300,7 @@ const reduceNonRange = new Transform({ 'addr:unit' in feature.properties ? ('addr:unit' in range.properties && feature.properties['addr:unit'] === range.properties['addr:unit']) : true && 'addr:flats' in feature.properties ? ('addr:flats' in range.properties && feature.properties['addr:flats'] === range.properties['addr:flats']) : true ) { + dropReason = `Dropped due to existing range ${range.properties['addr:housenumber']} ${range.properties['addr:street']} ${range.properties._pfi ? '(' + range.properties._pfi + ')' : ''} where flats and unit match` dropFeature = true } else { // since the non-range feature has a unit that the range doesn't have, don't drop it @@ -319,6 +321,7 @@ const reduceNonRange = new Transform({ } } else { // no addr:unit or addr:flats on the feature to safe to drop + dropReason = `Dropped due to existing range ${range.properties['addr:housenumber']} ${range.properties['addr:street']} ${range.properties._pfi ? '(' + range.properties._pfi + ')' : ''} without flats or unit to check` dropFeature = true } break @@ -333,6 +336,7 @@ const reduceNonRange = new Transform({ console.log(`Filter B: Dropping ${feature.properties['addr:housenumber']}`) } if (argv.debug) { + feature.properties._dropReason = dropReason debugStreams['filterB'].write(feature) } } diff --git a/lib/withinRange.js b/lib/withinRange.js index 3408a5a..7b6aa18 100644 --- a/lib/withinRange.js +++ b/lib/withinRange.js @@ -1,10 +1,12 @@ /** * @param {Object} feature * @param {Object} rangeFeature + * @param {Object} options + * @param {boolean} options.matchParity - if the parity of the number must match the range to be considered within (eg. if true, then 2 would not be within 1-3 but would be within 2-4 or within 0-4) * * @returns {boolean} True if addr:housenumber of feature is within the range of addr:housenumber rangeFeature and all other addr:* attributes match */ -module.exports = (feature, rangeFeature) => { +module.exports = (feature, rangeFeature, options) => { const regexp = /^(?<pre>\D*)(?<num>\d*)(?<suf>\D*)$/ if ( @@ -33,7 +35,19 @@ module.exports = (feature, rangeFeature) => { Number(i.num) >= Number(from.num) && Number(i.num) <= Number(to.num) ) { // feature within featureRange (ignore prefix/suffix) - return true + if (options && options.matchParity) { + // if parity matches (ie. both number and from/to are even, or both are odd, but not one even and one odd) + if ( + ((Number(i.num) % 2) === (Number(from.num) % 2)) && + ((Number(i.num) % 2) === (Number(to.num) % 2)) + ) { + return true + } else { + return false + } + } else { + return true + } } else { return false } diff --git a/test/withinRange.js b/test/withinRange.js index 5dd349c..8d46eba 100644 --- a/test/withinRange.js +++ b/test/withinRange.js @@ -131,5 +131,17 @@ test('withinRange', t => { '12C not within 118-120' ) + t.same( + withinRange(B, AC, { matchParity: true }), + false, + 'B not within AC when matching parity' + ) + + t.same( + withinRange(A, AC, { matchParity: true }), + true, + 'A within AC when matching parity' + ) + t.end() }) |