From 0275d9e79da1f72044737fb0fbcaa4f136f09c6f Mon Sep 17 00:00:00 2001 From: Andrew Harvey Date: Mon, 5 Jul 2021 12:01:04 +1000 Subject: update within range to accept comparing ranges --- lib/withinRange.js | 60 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 11 deletions(-) (limited to 'lib') diff --git a/lib/withinRange.js b/lib/withinRange.js index 7b6aa18..b86da82 100644 --- a/lib/withinRange.js +++ b/lib/withinRange.js @@ -1,38 +1,76 @@ /** * @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) + * @param {Object} [options] + * @param {boolean} [options.matchParity=false] - 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) + * @param {boolean} [options.checkHigherOrderAddrKeys=true] - if true checks that addr:suburb, addr:state, addr:postcode also match + * @param {boolean} [options.checkStreet=true] - if true checks that addr:street matches * * @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, options) => { const regexp = /^(?
\D*)(?\d*)(?\D*)$/
 
+  const checkStreet = options && 'checkStreet' in options ? options.checkStreet : true
+  const checkHigherOrderAddrKeys = options && 'checkHigherOrderAddrKeys' in options ? options.checkHigherOrderAddrKeys : true
+
   if (
     // must have a housenumber
     'addr:housenumber' in feature.properties &&
     'addr:housenumber' in rangeFeature.properties &&
 
     // must have a street and street must match
-    'addr:street' in feature.properties &&
-    'addr:street' in rangeFeature.properties &&
-    feature.properties['addr:street'] === rangeFeature.properties['addr:street'] &&
+    (
+      checkStreet ? (
+        'addr:street' in feature.properties &&
+        'addr:street' in rangeFeature.properties &&
+        (feature.properties['addr:street'] || '').toLowerCase().replaceAll(' ', '') === (rangeFeature.properties['addr:street'] || '').toLowerCase().replaceAll(' ', '')
+      ) : true
+    ) &&
 
     // other higher attributes must match if exists
-    feature.properties['addr:suburb'] === rangeFeature.properties['addr:suburb'] &&
-    feature.properties['addr:state'] === rangeFeature.properties['addr:state'] &&
-    feature.properties['addr:postcode'] === rangeFeature.properties['addr:postcode']
+    (
+      checkHigherOrderAddrKeys ? (
+        feature.properties['addr:suburb'] === rangeFeature.properties['addr:suburb'] &&
+        feature.properties['addr:state'] === rangeFeature.properties['addr:state'] &&
+        feature.properties['addr:postcode'] === rangeFeature.properties['addr:postcode']
+      ) : true
+    )
   ) {
     const rangeParts = rangeFeature.properties['addr:housenumber'].split('-')
     if (rangeParts.length === 2) {
+      const fromMatch = rangeParts[0].match(regexp)
+      const toMatch = rangeParts[1].match(regexp)
+
+      if (!fromMatch || !toMatch) {
+        console.log(`range ${rangeFeature.properties['addr:housenumber']} didn't match regexp`, rangeFeature)
+        return false
+      }
       const from = rangeParts[0].match(regexp).groups
       const to = rangeParts[1].match(regexp).groups
 
-      const i = feature.properties['addr:housenumber'].match(regexp).groups
+      const iParts = feature.properties['addr:housenumber'].split('-')
+      let iFrom
+      let iTo
+      let iRange = false
+      if (iParts.length === 2) {
+        iRange = true
+        iFrom = iParts[0].match(regexp).groups
+        iTo = iParts[1].match(regexp).groups
+      }
+      const i = !iRange ? feature.properties['addr:housenumber'].match(regexp).groups : null
       if (
-        Number.isInteger(Number(i.num)) && Number.isInteger(Number(from.num)) && Number.isInteger(Number(to.num)) &&
-        Number(i.num) >= Number(from.num) && Number(i.num) <= Number(to.num)
+        iRange ? (
+          Number.isInteger(Number(iFrom.num)) && Number.isInteger(Number(iTo.num)) && Number.isInteger(Number(from.num)) && Number.isInteger(Number(to.num)) &&
+          (
+            (Number(iFrom.num) >= Number(from.num) && Number(iFrom.num) <= Number(to.num))
+            ||
+            (Number(iTo.num) >= Number(from.num) && Number(iTo.num) <= Number(to.num))
+          )
+        ) : (
+          Number.isInteger(Number(i.num)) && Number.isInteger(Number(from.num)) && Number.isInteger(Number(to.num)) &&
+          Number(i.num) >= Number(from.num) && Number(i.num) <= Number(to.num)
+        )
       ) {
         // feature within featureRange (ignore prefix/suffix)
         if (options && options.matchParity) {
-- 
cgit v1.2.3