pelias-openstreetmap 7.3.0 → 7.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/schema/address_karlsruhe.js +1 -1
- package/schema/address_naptan.js +1 -1
- package/schema/address_osm.js +1 -1
- package/schema/address_tiger.js +1 -1
- package/schema/name_osm.js +1 -14
- package/stream/address_extractor.js +12 -12
- package/stream/tag_mapper.js +41 -34
- package/util/parseSemicolonDelimitedValues.js +14 -0
package/package.json
CHANGED
package/schema/address_naptan.js
CHANGED
package/schema/address_osm.js
CHANGED
package/schema/address_tiger.js
CHANGED
package/schema/name_osm.js
CHANGED
|
@@ -14,16 +14,13 @@
|
|
|
14
14
|
When multiple keys have the value 'default' then they are considered
|
|
15
15
|
as aliases of the default field.
|
|
16
16
|
|
|
17
|
-
The '_primary' property defined below defines which of those aliases
|
|
18
|
-
is considered the 'primary default name' for label generation.
|
|
19
|
-
|
|
20
17
|
No values other than 'default' should be specified more than once.
|
|
21
18
|
|
|
22
19
|
@ref: http://wiki.openstreetmap.org/wiki/Key:name
|
|
23
20
|
@ref: http://wiki.openstreetmap.org/wiki/Names
|
|
24
21
|
**/
|
|
25
22
|
|
|
26
|
-
|
|
23
|
+
const OSM_NAMING_SCHEMA = {
|
|
27
24
|
'name': 'default',
|
|
28
25
|
'loc_name': 'default',
|
|
29
26
|
'alt_name': 'default',
|
|
@@ -38,14 +35,4 @@ var OSM_NAMING_SCHEMA = {
|
|
|
38
35
|
// 'sorting_name': 'sorting'
|
|
39
36
|
};
|
|
40
37
|
|
|
41
|
-
// this property is considered the 'primary name'
|
|
42
|
-
// for label generation, the others are considered
|
|
43
|
-
// secondary or 'aliases'.
|
|
44
|
-
Object.defineProperty(OSM_NAMING_SCHEMA, '_primary', {
|
|
45
|
-
value: 'name',
|
|
46
|
-
enumerable: false,
|
|
47
|
-
configurable: false,
|
|
48
|
-
writable: false
|
|
49
|
-
});
|
|
50
|
-
|
|
51
38
|
module.exports = OSM_NAMING_SCHEMA;
|
|
@@ -23,11 +23,12 @@
|
|
|
23
23
|
not searchable.
|
|
24
24
|
**/
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
const through = require('through2');
|
|
27
|
+
const isObject = require('is-object');
|
|
28
|
+
const extend = require('extend');
|
|
29
|
+
const peliasLogger = require( 'pelias-logger' ).get( 'openstreetmap' );
|
|
30
|
+
const Document = require('pelias-model').Document;
|
|
31
|
+
const parseSemicolonDelimitedValues = require('../util/parseSemicolonDelimitedValues');
|
|
31
32
|
|
|
32
33
|
function hasValidAddress( doc ){
|
|
33
34
|
if( !isObject( doc ) ){ return false; }
|
|
@@ -42,21 +43,20 @@ function hasValidAddress( doc ){
|
|
|
42
43
|
module.exports = function(){
|
|
43
44
|
|
|
44
45
|
var stream = through.obj( function( doc, enc, next ) {
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
const isNamedPoi = !!doc.getName('default');
|
|
47
|
+
const isAddress = hasValidAddress( doc );
|
|
47
48
|
|
|
48
49
|
// accept semi-colon delimited house numbers
|
|
49
50
|
// ref: https://github.com/pelias/openstreetmap/issues/21
|
|
50
|
-
|
|
51
|
+
const streetNumbers = parseSemicolonDelimitedValues(doc.getAddress('number'));
|
|
51
52
|
|
|
52
53
|
// create a new record for street addresses
|
|
53
54
|
if( isAddress ){
|
|
54
|
-
var record;
|
|
55
|
-
|
|
56
55
|
streetNumbers.forEach( function( streetno, i ){
|
|
56
|
+
let record;
|
|
57
57
|
|
|
58
58
|
try {
|
|
59
|
-
|
|
59
|
+
const newid = [ doc.getSourceId() ];
|
|
60
60
|
if( i > 0 ){
|
|
61
61
|
newid.push( i );
|
|
62
62
|
peliasLogger.debug('[address_extractor] found multiple house numbers: ', streetNumbers);
|
|
@@ -116,7 +116,7 @@ module.exports = function(){
|
|
|
116
116
|
};
|
|
117
117
|
|
|
118
118
|
// properties to map from the osm record to the pelias doc
|
|
119
|
-
|
|
119
|
+
const addrProps = [ 'name', 'number', 'street', 'zip' ];
|
|
120
120
|
|
|
121
121
|
// call document setters and ignore non-fatal errors
|
|
122
122
|
function setProperties( record, doc ){
|
package/stream/tag_mapper.js
CHANGED
|
@@ -7,10 +7,11 @@
|
|
|
7
7
|
const _ = require('lodash');
|
|
8
8
|
const through = require('through2');
|
|
9
9
|
const peliasLogger = require('pelias-logger').get('openstreetmap');
|
|
10
|
+
const parseSemicolonDelimitedValues = require('../util/parseSemicolonDelimitedValues');
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
const LOCALIZED_NAME_KEYS = require('../config/localized_name_keys');
|
|
13
|
+
const NAME_SCHEMA = require('../schema/name_osm');
|
|
14
|
+
const ADDRESS_SCHEMA = _.merge( {},
|
|
14
15
|
require('../schema/address_tiger'),
|
|
15
16
|
require('../schema/address_osm'),
|
|
16
17
|
require('../schema/address_naptan'),
|
|
@@ -19,7 +20,7 @@ var ADDRESS_SCHEMA = _.merge( {},
|
|
|
19
20
|
|
|
20
21
|
module.exports = function(){
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
const stream = through.obj( function( doc, enc, next ) {
|
|
23
24
|
|
|
24
25
|
try {
|
|
25
26
|
|
|
@@ -35,34 +36,39 @@ module.exports = function(){
|
|
|
35
36
|
|
|
36
37
|
// Map localized names which begin with 'name:'
|
|
37
38
|
// @ref: http://wiki.openstreetmap.org/wiki/Namespace#Language_code_suffix
|
|
38
|
-
|
|
39
|
-
if(
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
39
|
+
const langCode = getNameSuffix( key );
|
|
40
|
+
if( langCode ){
|
|
41
|
+
const langValues = parseSemicolonDelimitedValues( value );
|
|
42
|
+
langValues.forEach(( langValue, i ) => {
|
|
43
|
+
if ( i === 0 ) {
|
|
44
|
+
doc.setName( langCode, langValue );
|
|
45
|
+
} else {
|
|
46
|
+
doc.setNameAlias( langCode, langValue );
|
|
47
|
+
}
|
|
48
|
+
});
|
|
44
49
|
}
|
|
45
50
|
|
|
46
51
|
// Map name data from our name mapping schema
|
|
47
52
|
else if( _.has(NAME_SCHEMA, key) ){
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
} else {
|
|
55
|
-
doc.setName( NAME_SCHEMA[key], val2 );
|
|
53
|
+
const nameValues = parseSemicolonDelimitedValues( cleanString( value ) );
|
|
54
|
+
nameValues.forEach(( nameValue, i ) => {
|
|
55
|
+
// For the primary name key 'name', ensure it is the first value
|
|
56
|
+
if( 'name' === key && i === 0 ){
|
|
57
|
+
doc.setName(NAME_SCHEMA[key], nameValue);
|
|
58
|
+
return;
|
|
56
59
|
}
|
|
57
|
-
|
|
60
|
+
|
|
61
|
+
// Otherwise set as an alias
|
|
62
|
+
doc.setNameAlias( NAME_SCHEMA[key], nameValue );
|
|
63
|
+
});
|
|
58
64
|
}
|
|
59
65
|
|
|
60
66
|
// Map address data from our address mapping schema
|
|
61
67
|
else if( _.has(ADDRESS_SCHEMA, key) ){
|
|
62
|
-
|
|
63
|
-
if(
|
|
64
|
-
|
|
65
|
-
doc.setAddress(label, normalizeAddressField(label,
|
|
68
|
+
const addrValue = cleanString( value );
|
|
69
|
+
if( addrValue ){
|
|
70
|
+
const label = ADDRESS_SCHEMA[key];
|
|
71
|
+
doc.setAddress(label, normalizeAddressField(label, addrValue));
|
|
66
72
|
}
|
|
67
73
|
}
|
|
68
74
|
});
|
|
@@ -71,21 +77,22 @@ module.exports = function(){
|
|
|
71
77
|
// other names which we could use as the default.
|
|
72
78
|
if( !doc.getName('default') ){
|
|
73
79
|
|
|
74
|
-
|
|
75
|
-
_.get(tags, 'official_name')
|
|
76
|
-
_.get(tags, 'int_name')
|
|
77
|
-
_.get(tags, 'nat_name')
|
|
78
|
-
_.get(tags, 'reg_name')
|
|
79
|
-
doc.getName('en')
|
|
80
|
+
const defaultName = [
|
|
81
|
+
...parseSemicolonDelimitedValues(_.get(tags, 'official_name')),
|
|
82
|
+
...parseSemicolonDelimitedValues(_.get(tags, 'int_name')),
|
|
83
|
+
...parseSemicolonDelimitedValues(_.get(tags, 'nat_name')),
|
|
84
|
+
...parseSemicolonDelimitedValues(_.get(tags, 'reg_name')),
|
|
85
|
+
...parseSemicolonDelimitedValues(doc.getName('en'))
|
|
86
|
+
].filter(Boolean);
|
|
80
87
|
|
|
81
88
|
// use one of the preferred name tags listed above
|
|
82
|
-
if ( defaultName ){
|
|
83
|
-
doc.setName('default', defaultName);
|
|
89
|
+
if ( defaultName.length ){
|
|
90
|
+
doc.setName('default', defaultName[0]);
|
|
84
91
|
}
|
|
85
92
|
|
|
86
93
|
// else try to use an available two-letter language name tag
|
|
87
94
|
else {
|
|
88
|
-
|
|
95
|
+
const keys = Object.keys(doc.name).filter(n => n.length === 2);
|
|
89
96
|
|
|
90
97
|
// unambiguous (there is only a single two-letter name tag)
|
|
91
98
|
if ( keys.length === 1 ){
|
|
@@ -101,7 +108,7 @@ module.exports = function(){
|
|
|
101
108
|
// Import airport codes as aliases
|
|
102
109
|
if( tags.hasOwnProperty('aerodrome') || tags.hasOwnProperty('aeroway') ){
|
|
103
110
|
if( tags.hasOwnProperty('iata') ){
|
|
104
|
-
|
|
111
|
+
const iata = cleanString( tags.iata );
|
|
105
112
|
if( iata ){
|
|
106
113
|
doc.setNameAlias( 'default', iata );
|
|
107
114
|
doc.setNameAlias( 'default', `${iata} Airport` );
|
|
@@ -127,7 +134,7 @@ module.exports = function(){
|
|
|
127
134
|
};
|
|
128
135
|
|
|
129
136
|
// Clean string of leading/trailing junk chars
|
|
130
|
-
function
|
|
137
|
+
function cleanString( str ){
|
|
131
138
|
return _.trim( str, '#$%^*<>-=_{};:",./?\t\n\' ' );
|
|
132
139
|
}
|
|
133
140
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const _ = require('lodash');
|
|
2
|
+
|
|
3
|
+
// Split multi-value OSM tags into an Array
|
|
4
|
+
// https://wiki.openstreetmap.org/wiki/Talk:Semi-colon_value_separator
|
|
5
|
+
function parseSemicolonDelimitedValues(value) {
|
|
6
|
+
return (_.isString(value) ? value : '')
|
|
7
|
+
.split(';')
|
|
8
|
+
// Historical Landmark: former site of The Most Clever Line of JavaScript
|
|
9
|
+
// https://blog.bloomca.me/2017/11/08/the-most-clever-line-of-javascript.html
|
|
10
|
+
.map(v => v.trim())
|
|
11
|
+
.filter(v => v.length);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
module.exports = parseSemicolonDelimitedValues;
|