Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improved support for streets with no suffix, such as "broadway" #141

Merged
merged 1 commit into from
Aug 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions classification/StreetProperNameClassification.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const Classification = require('./Classification')

class StreetProperNameClassification extends Classification {
constructor (confidence, meta) {
super(confidence, meta)
this.label = 'street_proper_name'
}
}

module.exports = StreetProperNameClassification
24 changes: 24 additions & 0 deletions classification/StreetProperNameClassification.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const Classification = require('./StreetProperNameClassification')

module.exports.tests = {}

module.exports.tests.constructor = (test) => {
test('constructor', (t) => {
let c = new Classification()
t.false(c.public)
t.equals(c.label, 'street_proper_name')
t.equals(c.confidence, 1.0)
t.deepEqual(c.meta, {})
t.end()
})
}

module.exports.all = (tape, common) => {
function test (name, testFunction) {
return tape(`StreetProperNameClassification: ${name}`, testFunction)
}

for (var testCase in module.exports.tests) {
module.exports.tests[testCase](test, common)
}
}
5 changes: 3 additions & 2 deletions classifier/CompositeClassifier.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,9 @@ class CompositeClassifier extends SectionClassifier {
// find phrases which equal the composites
let superPhrases = []
composites.forEach(c => {
let start = c[0].start
let end = c[c.length - 1].end
var carr = Array.isArray(c) ? c : [c] // cast to array
let start = carr[0].start
let end = carr[carr.length - 1].end
superPhrases = superPhrases.concat(phrases.filter(p => p.start === start && p.end === end))
})

Expand Down
29 changes: 29 additions & 0 deletions classifier/StreetProperNameClassifier.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const WordClassifier = require('./super/WordClassifier')
const StreetProperNameClassification = require('../classification/StreetProperNameClassification')

/**
Special handling of streets with no suffix

see: https://github.com/pelias/parser/issues/140
**/

class StreetProperNameClassifier extends WordClassifier {
setup () {
this.index = {
'broadway': true,
'esplanade': true
}
}

each (span) {
// skip spans which contain numbers
if (span.contains.numerals) { return }

// classify tokens in the index as 'street_proper_name'
if (this.index[span.norm] === true) {
span.classify(new StreetProperNameClassification(0.7))
}
}
}

module.exports = StreetProperNameClassifier
49 changes: 49 additions & 0 deletions classifier/StreetProperNameClassifier.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
const StreetProperNameClassifier = require('./StreetProperNameClassifier')
const StreetProperNameClassification = require('../classification/StreetProperNameClassification')
const Span = require('../tokenization/Span')
const classifier = new StreetProperNameClassifier()

module.exports.tests = {}

function classify (body) {
let s = new Span(body)
classifier.each(s, null, 1)
return s
}

module.exports.tests.contains_numerals = (test) => {
test('contains numerals: honours contains.numerals boolean', (t) => {
let s = new Span('example')
s.contains.numerals = true
classifier.each(s, null, 1)
t.deepEqual(s.classifications, {})
t.end()
})
}

module.exports.tests.street_proper_names = (test) => {
let valid = [
'broadway',
'esplanade'
]

valid.forEach(token => {
test(`street_proper_names: ${token}`, (t) => {
let s = classify(token)
t.deepEqual(s.classifications, {
StreetProperNameClassification: new StreetProperNameClassification(0.7)
})
t.end()
})
})
}

module.exports.all = (tape, common) => {
function test (name, testFunction) {
return tape(`StreetProperNameClassifier: ${name}`, testFunction)
}

for (var testCase in module.exports.tests) {
module.exports.tests[testCase](test, common)
}
}
26 changes: 26 additions & 0 deletions classifier/scheme/street.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,32 @@ module.exports = [
}
]
},
{
// Broadway Market
confidence: 0.80,
Class: StreetClassification,
scheme: [
{
is: ['StreetProperNameClassification'],
not: ['StreetClassification', 'IntersectionClassification']
},
{
is: ['StreetSuffixClassification'],
not: ['StreetClassification', 'IntersectionClassification']
}
]
},
{
// Broadway
confidence: 0.82,
Class: StreetClassification,
scheme: [
{
is: ['StreetProperNameClassification'],
not: ['StreetClassification', 'IntersectionClassification']
}
]
},
{
// +++ Main Street
confidence: 0.84,
Expand Down
2 changes: 2 additions & 0 deletions parser/AddressParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const UnitTypeUnitClassifier = require('../classifier/UnitTypeUnitClassifier')
const PostcodeClassifier = require('../classifier/PostcodeClassifier')
const StreetPrefixClassifier = require('../classifier/StreetPrefixClassifier')
const StreetSuffixClassifier = require('../classifier/StreetSuffixClassifier')
const StreetProperNameClassifier = require('../classifier/StreetProperNameClassifier')
const RoadTypeClassifier = require('../classifier/RoadTypeClassifier')
const ToponymClassifier = require('../classifier/ToponymClassifier')
const CompoundStreetClassifier = require('../classifier/CompoundStreetClassifier')
Expand Down Expand Up @@ -56,6 +57,7 @@ class AddressParser extends Parser {
new PostcodeClassifier(),
new StreetPrefixClassifier(),
new StreetSuffixClassifier(),
new StreetProperNameClassifier(),
new RoadTypeClassifier(),
new ToponymClassifier(),
new CompoundStreetClassifier(),
Expand Down
4 changes: 4 additions & 0 deletions resources/pelias/dictionaries/libpostal/en/street_types.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@ furlong
# 1384 Cambridge beltway, Cambridge, MD 21613, USA
beltway

# https://github.com/pelias/parser/issues/140
!broadway|bdwy|bway|bwy|brdway
!esplanade|esp|espl
market
3 changes: 3 additions & 0 deletions resources/pelias/dictionaries/libpostal/fr/street_types.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
cité|cite
cités|cites

# https://github.com/pelias/parser/pull/141#issuecomment-895230721
!esplanades|esps
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,7 @@ bronx
!wisconsin
!wyoming

# https://github.com/pelias/parser/issues/140
!broadway
!esplanade
!market
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# https://github.com/pelias/parser/issues/140
!broadway
10 changes: 10 additions & 0 deletions test/address.deu.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,21 @@ const testcase = (test, common) => {
{ locality: 'Munich' }, { country: 'Germany' }
])

assert('Esplanade, Berlin', [
{ street: 'Esplanade' },
{ locality: 'Berlin' }
])

assert('Esplanade 17, Berlin', [
{ street: 'Esplanade' }, { housenumber: '17' },
{ locality: 'Berlin' }
])

assert('17 Esplanade, Berlin', [
{ housenumber: '17' }, { street: 'Esplanade' },
{ locality: 'Berlin' }
])

assert('Königsallee Düsseldorf', [
{ street: 'Königsallee' },
{ locality: 'Düsseldorf' }
Expand Down
5 changes: 5 additions & 0 deletions test/address.fra.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ const testcase = (test, common) => {
assert(`Paris 75000, France`, [
{ locality: 'Paris' }, { postcode: '75000' }, { country: 'France' }
])

// https://github.com/pelias/parser/pull/141#issuecomment-895230721
assert(`Esplanade de la Liberté`, [{ street: 'Esplanade de la Liberté' }])
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for those test cases, I had actually broken the street prefix Esplanade for French addresses 😱, but managed to fix them again after adding the examples 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😅 nice !

assert(`Esplanade du Géneral de Gaulle`, [{ street: 'Esplanade du Géneral de Gaulle' }])
assert(`Esplanade Méditerranée`, [{ street: 'Esplanade Méditerranée' }])
}

module.exports.all = (tape, common) => {
Expand Down
13 changes: 13 additions & 0 deletions test/address.gbr.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@ const testcase = (test, common) => {
assert('Rushendon Furlong', [
{ street: 'Rushendon Furlong' }
])

// Valid street name in London
assert('Broadway Market, London', [
{ street: 'Broadway Market' },
{ locality: 'London' }
])

// 'The Dove', a pub on Broadway Market
assert('24-28 Broadway Market, London', [
{ housenumber: '24-28' },
{ street: 'Broadway Market' },
{ locality: 'London' }
])
}

module.exports.all = (tape, common) => {
Expand Down
30 changes: 30 additions & 0 deletions test/address.usa.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,36 @@ const testcase = (test, common) => {
{ locality: 'boston' },
{ region: 'ma' }
])

// https://github.com/pelias/parser/issues/140
assert('Broadway, Manhattan', [
{ street: 'Broadway' },
{ locality: 'Manhattan' }
])
assert('24 Broadway, Manhattan', [
{ housenumber: '24' }, { street: 'Broadway' },
{ locality: 'Manhattan' }
])
assert('Broadway 24, Manhattan', [
{ street: 'Broadway' }, { housenumber: '24' },
{ locality: 'Manhattan' }
])
assert('East Broadway, Manhattan', [
{ street: 'East Broadway' },
{ locality: 'Manhattan' }
])
assert('24 East Broadway, Manhattan', [
{ housenumber: '24' }, { street: 'East Broadway' },
{ locality: 'Manhattan' }
])
assert('West Broadway, Manhattan', [
{ street: 'West Broadway' },
{ locality: 'Manhattan' }
])
assert('24 West Broadway, Manhattan', [
{ housenumber: '24' }, { street: 'West Broadway' },
{ locality: 'Manhattan' }
])
}

module.exports.all = (tape, common) => {
Expand Down