Skip to content

Commit 01cb65d

Browse files
Bimbolpbieniek
andauthored
feat: import addresses which use addr:place instead of addr:street (#565)
* added: missing street schema * added: "addr: place" support * added: "addr: place" support * docs: stream * refaktor: sugesstions from code review Co-authored-by: pbieniek <patryk.bieniek@stava.pl>
1 parent 1e83d4a commit 01cb65d

7 files changed

Lines changed: 165 additions & 3 deletions

File tree

config/features.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66

77
// default tags imported
88
const tags = [
9-
'addr:housenumber+addr:street'
9+
'addr:housenumber+addr:street',
10+
'addr:housenumber+addr:place' // @ref https://github.com/pelias/pelias/issues/787#issuecomment-477137803
1011
];
1112

1213
// tags corresponding to venues

schema/address_karlsruhe.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@ var KARLSRUHE_SCHEMA = {
2222
// 'addr:country': 'country'
2323
};
2424

25-
module.exports = KARLSRUHE_SCHEMA;
25+
module.exports = KARLSRUHE_SCHEMA;

stream/addresses_without_street.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
2+
/**
3+
This stream is responsible for filling 'addr:street' if is empty or missing,
4+
with 'addr:place' value. Note that both 'addr:place' and 'addr:housenumber'
5+
must be present inside tags!
6+
7+
@ref https://github.com/pelias/openstreetmap/pull/565
8+
**/
9+
10+
const _ = require('lodash');
11+
const through = require('through2');
12+
const peliasLogger = require('pelias-logger').get('openstreetmap');
13+
14+
15+
module.exports = function(){
16+
17+
var stream = through.obj( function( doc, enc, next ) {
18+
19+
try {
20+
21+
// skip records with no tags
22+
var tags = doc.getMeta('tags');
23+
if( !tags ){
24+
return next( null, doc );
25+
}
26+
27+
// housenumber is required
28+
if (!_.has(tags, 'addr:housenumber')){
29+
return next( null, doc );
30+
}
31+
32+
const street = _.get(tags, 'addr:street', '').trim();
33+
const place = _.get(tags, 'addr:place', '').trim();
34+
35+
// when street is unset but place is set, use place for the street name
36+
if (_.isEmpty(street) && !_.isEmpty(place)) {
37+
_.set(tags, 'addr:street', place);
38+
}
39+
}
40+
41+
catch( e ){
42+
peliasLogger.error( 'addresses_without_street error' );
43+
peliasLogger.error( e.stack );
44+
peliasLogger.error( JSON.stringify( doc, null, 2 ) );
45+
}
46+
47+
return next( null, doc );
48+
49+
});
50+
51+
// catch stream errors
52+
stream.on( 'error', peliasLogger.error.bind( peliasLogger, __filename ) );
53+
54+
return stream;
55+
};

stream/importPipeline.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ streams.pbfParser = require('./multiple_pbfs').create;
1010
streams.docConstructor = require('./document_constructor');
1111
streams.blacklistStream = require('pelias-blacklist-stream');
1212
streams.tagMapper = require('./tag_mapper');
13+
streams.addressesWithoutStreet = require('./addresses_without_street');
1314
streams.adminLookup = require('pelias-wof-admin-lookup').create;
1415
streams.addressExtractor = require('./address_extractor');
1516
streams.categoryMapper = require('./category_mapper');
@@ -22,6 +23,7 @@ streams.elasticsearch = require('pelias-dbclient');
2223
streams.import = function(){
2324
streams.pbfParser()
2425
.pipe( streams.docConstructor() )
26+
.pipe( streams.addressesWithoutStreet() )
2527
.pipe( streams.tagMapper() )
2628
.pipe( streams.addressExtractor() )
2729
.pipe( streams.blacklistStream() )

test/run.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ var tests = [
1616
require('./stream/importPipeline'),
1717
require('./stream/pbf'),
1818
require('./stream/stats'),
19-
require('./stream/tag_mapper')
19+
require('./stream/tag_mapper'),
20+
require('./stream/addresses_without_street')
2021
];
2122

2223
tests.map(function(t) {
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
2+
const through = require('through2');
3+
const mapper = require('../../stream/addresses_without_street');
4+
const Document = require('pelias-model').Document;
5+
6+
module.exports.tests = {};
7+
8+
// test exports
9+
module.exports.tests.interface = function(test, common) {
10+
test('interface: factory', function(t) {
11+
t.equal(typeof mapper, 'function', 'stream factory');
12+
t.end();
13+
});
14+
test('interface: stream', function(t) {
15+
var stream = mapper();
16+
t.equal(typeof stream, 'object', 'valid stream');
17+
t.equal(typeof stream._read, 'function', 'valid readable');
18+
t.equal(typeof stream._write, 'function', 'valid writeable');
19+
t.end();
20+
});
21+
};
22+
23+
// a tags with missing required extra tag (addr:housenumber)
24+
// should pass through the stream without being modified.
25+
// @ref https://github.com/pelias/openstreetmap/pull/565#issuecomment-1062874227
26+
module.exports.tests.passthrough = function(test, common) {
27+
test('passthrough: missing addr:housenumber tag', function(t) {
28+
var original = new Document('a','b', 1);
29+
original.setMeta('tags', { 'addr:place': 'L14' });
30+
var stream = mapper();
31+
stream.pipe( through.obj( function( doc, enc, next ){
32+
t.deepEqual(doc.getMeta('tags'), original.getMeta('tags'), 'tags not modified' );
33+
t.end(); // test will fail if not called (or called twice).
34+
next();
35+
}));
36+
stream.write(original);
37+
});
38+
};
39+
40+
// // ======================== addresses =========================
41+
42+
module.exports.tests.karlsruhe_schema = function(test, common) {
43+
test('maps - karlsruhe schema with filled street', function(t) {
44+
var doc = new Document('a','b', 1);
45+
doc.setMeta('tags', { 'addr:street': 'BBB' });
46+
var stream = mapper();
47+
stream.pipe( through.obj( function( doc, enc, next ){
48+
var tags = doc.getMeta('tags');
49+
t.equal(tags['addr:street'], 'BBB', 'correctly mapped');
50+
t.end(); // test will fail if not called (or called twice).
51+
next();
52+
}));
53+
stream.write(doc);
54+
});
55+
test('maps - karlsruhe schema with empty street and filled place', function(t) {
56+
var doc = new Document('a','b', 1);
57+
doc.setMeta('tags', { 'addr:place': 'L14', 'addr:street': '', 'addr:housenumber': '14' });
58+
var stream = mapper();
59+
stream.pipe( through.obj( function( doc, enc, next ){
60+
var tags = doc.getMeta('tags');
61+
t.equal(tags['addr:street'], 'L14', 'correctly mapped');
62+
t.end(); // test will fail if not called (or called twice).
63+
next();
64+
}));
65+
stream.write(doc);
66+
});
67+
test('maps - karlsruhe schema without street and with filled place', function(t) {
68+
var doc = new Document('a','b', 1);
69+
doc.setMeta('tags', { 'addr:place': 'L14', 'addr:housenumber': '14' });
70+
var stream = mapper();
71+
stream.pipe( through.obj( function( doc, enc, next ){
72+
var tags = doc.getMeta('tags');
73+
t.equal(tags['addr:street'], 'L14', 'correctly mapped');
74+
t.end(); // test will fail if not called (or called twice).
75+
next();
76+
}));
77+
stream.write(doc);
78+
});
79+
test('maps - karlsruhe schema with both street and place', function(t) {
80+
var doc = new Document('a','b', 1);
81+
doc.setMeta('tags', { 'addr:place': 'L14', 'addr:street': 'BBB', 'addr:housenumber': '14' });
82+
var stream = mapper();
83+
stream.pipe( through.obj( function( doc, enc, next ){
84+
var tags = doc.getMeta('tags');
85+
t.equal(tags['addr:street'], 'BBB', 'correctly mapped');
86+
t.end(); // test will fail if not called (or called twice).
87+
next();
88+
}));
89+
stream.write(doc);
90+
});
91+
};
92+
93+
module.exports.all = function (tape, common) {
94+
95+
function test(name, testFunction) {
96+
return tape('address_without_street: ' + name, testFunction);
97+
}
98+
99+
for( var testCase in module.exports.tests ){
100+
module.exports.tests[testCase](test, common);
101+
}
102+
};

test/stream/importPipeline.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ module.exports.tests.interface = function(test, common) {
1111
'pbfParser',
1212
'docConstructor',
1313
'blacklistStream',
14+
'addressesWithoutStreet',
1415
'tagMapper',
1516
'adminLookup',
1617
'addressExtractor',

0 commit comments

Comments
 (0)