aboutsummaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
Diffstat (limited to 'bin')
-rwxr-xr-xbin/reduceOverlap.js154
1 files changed, 69 insertions, 85 deletions
diff --git a/bin/reduceOverlap.js b/bin/reduceOverlap.js
index ab4f6e7..06b7911 100755
--- a/bin/reduceOverlap.js
+++ b/bin/reduceOverlap.js
@@ -79,105 +79,89 @@ const reduce = new Transform({
} else {
// mulitple features with the same geometry
- // if housenumber, street, suburb, state, postcode are all the same
- // and it's only unit which differs,
- // and there is an address with no unit
- // then remove all the unit addresses and add them as addr:flats on the no unit address
- const sameHousenumber = [...new Set(groupedFeatures.map(f => f.properties['addr:housenumber']))].length <= 1
- const sameStreet = [...new Set(groupedFeatures.map(f => f.properties['addr:street']))].length <= 1
- const sameSuburb = [...new Set(groupedFeatures.map(f => f.properties['addr:suburb']))].length <= 1
- const sameState = [...new Set(groupedFeatures.map(f => f.properties['addr:state']))].length <= 1
- const samePostcode = [...new Set(groupedFeatures.map(f => f.properties['addr:postcode']))].length <= 1
-
- const hasNonUnit = groupedFeatures.map(f => 'addr:unit' in f.properties).includes(false)
-
- if (sameHousenumber && sameStreet && sameSuburb && sameState && samePostcode) {
- if (hasNonUnit) {
- // all have same housenumber, street, suburb, state, postcode and there is a non-unit feature
- const nonUnitFeatures = groupedFeatures.filter(f => (!('addr:unit' in f.properties)))
- if (nonUnitFeatures.length > 1) {
- // multiple non-unit features, unsure how to reduce
- // TODO should these still be output to be picked up by ranges
- if (argv.debug) {
- groupedFeatures.forEach(feature => {
- debugStreams.multipleNonUnit.write(feature)
- })
- }
- } else {
- // a single non-unit feature exists
- const nonUnitFeature = cloneDeep(nonUnitFeatures[0])
+ // group by housenumber, street, suburb, state, postcode to reduce units into addr:flats
+ // groupedFeatures all all the features at the same point
+ const featuresGroupByNonUnit = {}
+ groupedFeatures.forEach(feature => {
+ const key = [
+ feature.properties['addr:housenumber'],
+ feature.properties['addr:street'],
+ feature.properties['addr:suburb'],
+ feature.properties['addr:state'],
+ feature.properties['addr:postcode']
+ ].join(';')
+
+ if (!(key in featuresGroupByNonUnit)) {
+ featuresGroupByNonUnit[key] = []
+ }
+
+ featuresGroupByNonUnit[key].push(feature)
+ })
- // place all the other addr:unit into addr:flats on the non-unit feature
- const allOtherUnits = groupedFeatures.filter(f => 'addr:unit' in f.properties).map(f => f.properties['addr:unit'])
+ Object.values(featuresGroupByNonUnit).forEach(featureGroup => {
+ if (featureGroup.length > 1) {
+ const hasNonUnit = featureGroup.map(f => 'addr:unit' in f.properties).includes(false)
- // if allOtherUnits.length is one then that means we have one address without a unit and one with a unit at the same point
- // in this case we just drop the non-unit address and keep the addr:unit one
- if (allOtherUnits.length === 1) {
+ if (hasNonUnit) {
+ // all have same housenumber, street, suburb, state, postcode and there is a non-unit feature
+ const nonUnitFeatures = featureGroup.filter(f => (!('addr:unit' in f.properties)))
+ if (nonUnitFeatures.length > 1) {
+ // multiple non-unit features, unsure how to reduce
+ // TODO should these still be output to be picked up by ranges
if (argv.debug) {
- groupedFeatures.forEach(feature => {
- debugStreams.oneUnitOneNonUnit.write(feature)
+ featureGroup.forEach(feature => {
+ debugStreams.multipleNonUnit.write(feature)
})
}
- this.push(allOtherUnits[0])
} else {
- // adapted from https://stackoverflow.com/a/54973116/6702659
- const sortedAllOtherUnitsAsRanges = allOtherUnits
- .slice()
- .sort((a, b) => a - b)
- .reduce((acc, cur, idx, src) => {
- if ((idx > 0) && ((cur - src[idx - 1]) === 1)) {
- acc[acc.length - 1][1] = cur
- } else {
- acc.push([cur])
- }
- return acc
- }, [])
- .map(range => range.join('-'))
-
- nonUnitFeature.properties['addr:flats'] = sortedAllOtherUnitsAsRanges.join(';')
- this.push(nonUnitFeature)
+ // a single non-unit feature exists
+ const nonUnitFeature = cloneDeep(nonUnitFeatures[0])
+
+ // place all the other addr:unit into addr:flats on the non-unit feature
+ const allOtherUnits = featureGroup.filter(f => 'addr:unit' in f.properties).map(f => f.properties['addr:unit'])
+
+ // if allOtherUnits.length is one then that means we have one address without a unit and one with a unit at the same point
+ // in this case we just drop the non-unit address and keep the addr:unit one
+ if (allOtherUnits.length === 1) {
+ if (argv.debug) {
+ featureGroup.forEach(feature => {
+ debugStreams.oneUnitOneNonUnit.write(feature)
+ })
+ }
+ this.push(allOtherUnits[0])
+ } else {
+ nonUnitFeature.properties['addr:flats'] = unitsToRanges(allOtherUnits)
+ // TODO should we set addr:flats:prefix from addr:unit:prefix?
+ this.push(nonUnitFeature)
+ }
}
- }
- } else {
- // all have same housenumber, street, suburb, state, postcode but no non-unit, ie. all with different unit values
- // combine all the addr:unit into addr:flats and then drop addr:unit
- const units = groupedFeatures.filter(f => 'addr:unit' in f.properties).map(f => f.properties['addr:unit'])
-
- if (units.length <= 1) {
- console.log(`all have same housenumber, street, suburb, state, postcode with no non-unit, but only found ${units.length} units`, units)
- process.exit(1)
- }
+ } else {
+ // all have same housenumber, street, suburb, state, postcode but no non-unit, ie. all with different unit values
+ // combine all the addr:unit into addr:flats and then drop addr:unit
+ const units = featureGroup.filter(f => 'addr:unit' in f.properties).map(f => f.properties['addr:unit'])
- const feature = cloneDeep(groupedFeatures[0])
- delete feature.properties['addr:unit']
+ if (units.length <= 1) {
+ console.log(`all have same housenumber, street, suburb, state, postcode with no non-unit, but only found ${units.length} units`, units)
+ process.exit(1)
+ }
- // adapted from https://stackoverflow.com/a/54973116/6702659
- const unitRanges = units
- .slice()
- .sort((a, b) => a - b)
- .reduce((acc, cur, idx, src) => {
- if ((idx > 0) && ((cur - src[idx - 1]) === 1)) {
- acc[acc.length - 1][1] = cur
- } else {
- acc.push([cur])
- }
- return acc
- }, [])
- .map(range => range.join('-'))
+ const feature = cloneDeep(featureGroup[0])
+ delete feature.properties['addr:unit']
- feature.properties['addr:flats'] = unitRanges.join(';')
- this.push(feature)
- }
- } else {
- // addresses with the same geometry, however more than unit differs
- // TODO need to investigate to see what we can/should do about these
- groupedFeatures.forEach(feature => {
+ feature.properties['addr:flats'] = unitsToRanges(units)
+ this.push(feature)
+ }
+ } else if (featureGroup.length === 1) {
+ // while other features share the same geometry, this one is unique in it's housenumber,street,suburb,state,postcode
+ // so output this feature, and we deal with the overlap at another stage
+ const feature = featureGroup[0]
this.push(feature)
+
if (argv.debug) {
debugStreams.sameGeometry.write(feature)
}
- })
- }
+ }
+ })
}
callback()