-
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(japanese): Add Japanese language variant for labels in Japan
- Loading branch information
1 parent
b943ac3
commit dbb7d25
Showing
5 changed files
with
278 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
const _ = require('lodash'); | ||
|
||
// get the value of a scalar, or the first element of an array if an array is passed | ||
function scalarOrFirstElement(param) { | ||
return _.isArray(param) ? param[0] : param; | ||
} | ||
|
||
function formatPostalCode(record) { | ||
if (record.postalcode) { | ||
return '〒' + record.postalcode; | ||
} | ||
} | ||
|
||
function buildAdminLabelPart(schema, record) { | ||
let labelParts = []; | ||
|
||
// iterate the admin components in the schema | ||
// the order of the properties in the file determine | ||
// the order of elements in this array | ||
for (const field in schema.valueFunctions) { | ||
const valueFunction = schema.valueFunctions[field]; | ||
|
||
labelParts.push(valueFunction(record)); | ||
} | ||
|
||
return labelParts; | ||
} | ||
|
||
// generally, our data from OA contains the 'chome' or district (similar to a neighbourhood) | ||
// in the street field, even though it really is not a street at all | ||
// detect this case and then return the street value | ||
function formatDistrictPart(record) { | ||
if (scalarOrFirstElement(record.name.default).includes(record.street)) { | ||
return record.street; | ||
} | ||
} | ||
|
||
// check for records with a standard Japanese building and block number in the housenumber field | ||
// these consist of two sets of numbers separated by a - | ||
// for Japanese format language, reformat them with the "番号" or "bango" characters | ||
function formatBlockPart(record) { | ||
const bangoRegex = new RegExp(/(\d+)-(\d+)/); | ||
|
||
const match = bangoRegex.exec(record.housenumber); | ||
if (match) { | ||
return `${match[1]}番${match[2]}号`; | ||
} | ||
|
||
return record.housenumber; | ||
} | ||
|
||
function venueName(record) { | ||
if (record.layer !== 'venue') { | ||
return; | ||
} | ||
|
||
return scalarOrFirstElement(record.name.ja) || scalarOrFirstElement(record.name.default); | ||
} | ||
|
||
// builds a complete label by combining several components | ||
// first, the postalcode if it exists, prefixed by the postal mark | ||
// second, administrative information like city | ||
// third, street/block level info if it exists, formatted as correctly as possible | ||
// finally, the venue name if it exists | ||
function japanBuilder(schema, record) { | ||
|
||
const postalcode = formatPostalCode(record); | ||
const admin = buildAdminLabelPart(schema, record); | ||
const distric = formatDistrictPart(record); | ||
const block = formatBlockPart(record); | ||
const venue = venueName(record); | ||
|
||
// combine components, inserting a space between the postalcode, admin, and name sections | ||
// when written on an envelope these would correspond to new lines, a space should help with some clarity | ||
let labelParts = _.concat(postalcode, ' ', admin, distric, block, ' ', venue); | ||
|
||
// retain only things that are truthy | ||
labelParts = _.compact(labelParts); | ||
|
||
return labelParts; | ||
} | ||
|
||
module.exports = japanBuilder; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
const generator = require('../labelGenerator'); | ||
|
||
module.exports.tests = {}; | ||
|
||
module.exports.tests.english_style_labels = function(test, common) { | ||
test('tokyo post office', function(t) { | ||
const doc = { | ||
name: { default: '東京中央郵便局' }, | ||
layer: 'venue', | ||
housenumber: '2', // this is incorrect but it's what we currently pull from OSM | ||
locality: ['東京'], | ||
county: ['千代田'], | ||
region: ['東京'], | ||
region_a: ['TK'], // should not be used | ||
postalcode: ['100-0005'], | ||
country_a: ['JPN'], // should not be used | ||
country: ['日本'], // should not be used (though this is up for debate) | ||
continent: ['アジア'], // should not be used | ||
}; | ||
|
||
const expected = '〒100-0005 ' + // postalcode with postal mark, plus a space (would be a newline on an envelope) | ||
'東京' + // region, tokyo-to | ||
'千代田' + // county, chyoda ward | ||
'東京' + // locality, tokyo | ||
'2 ' + // housenumber plus space to separate venue name | ||
'東京中央郵便局'; // venue name: 'Tokyo Central Post Office' | ||
t.equal(generator(doc, 'JPN'), expected); | ||
t.end(); | ||
}); | ||
|
||
test('tokyo address from OA', function(t) { | ||
const doc = { | ||
name: { default: '7-9 丸の内二丁目' }, | ||
layer: 'address', | ||
housenumber: '7-9', | ||
street: '丸の内二丁目', // Marunouchi 2-chome | ||
borough: ['千代田区'], // Chiyoda Ward | ||
locality: ['東京'], // Tokyo | ||
county: ['千代田'], // Chiyoda | ||
region: ['東京'], // Tokyo (should really be 東京都 for Tokyo-to) | ||
region_a: ['TK'], | ||
country: ['日本'], // Japan | ||
country_a: ['JPN'], | ||
continent: ['アジア'], // Asia | ||
}; | ||
|
||
const expected = '' + // no postalcode for this record | ||
'東京' + // prefecture (region), tokyo | ||
'千代田' + // county, chyoda | ||
'東京' + // designated city (locality), tokyo | ||
'千代田区' + // ward (borough), chiyoda ward | ||
'丸の内二丁目' + // district (street), Marunouchi 2-chome | ||
'7番9号'; // "bango" (block and building number) | ||
t.equal(generator(doc, 'JPN'), expected); | ||
t.end(); | ||
}); | ||
|
||
test('Shizuoka (smaller city near Tokyo) example from OA', function(t) { | ||
const doc = { | ||
name: { default: '331-8 中原' }, | ||
layer: 'address', | ||
housenumber: '331-8', | ||
street: '中原', | ||
// we should ideally have lower level admin info here, but we don't as of this writing | ||
locality: ['静岡市'], | ||
county: ['静岡'], | ||
region: ['東京'], // Tokyo (should really be 東京都 for Tokyo-to) | ||
region_a: ['SZ'], | ||
country: ['日本'], | ||
country_a: ['JPN'], | ||
continent: ['アジア'], | ||
}; | ||
|
||
const expected = '' + // no postalcode for this record | ||
'東京' + // prefecture (region), tokyo | ||
'静岡' + // city (county), Shizuoka | ||
'静岡市' + // designated city (locality), Shizuoka-shi | ||
'中原' + // chome/ward (street), Nakahara | ||
'331番8号'; // "bango" (block and building number) | ||
t.equal(generator(doc, 'JPN'), expected); | ||
t.end(); | ||
}); | ||
|
||
test('address in Sapporo from OA', function(t) { | ||
const doc = { | ||
name: { default: '2-12 北二十四条西四丁目' }, | ||
layer: 'address', | ||
housenumber: '2-12', | ||
street: '北二十四条西四丁目', | ||
locality: ['札幌市'], | ||
county: ['札幌'], | ||
region: ['北海'], | ||
region_a: ['HK'], | ||
country: ['日本'], | ||
country_a: ['JPN'], | ||
continent: ['アジア'], | ||
}; | ||
const expected = '' + // no postalcode for this record | ||
'北海' + // prefecture (region), Hokkaido Prefecture | ||
'札幌' + // city (county), Sapporo | ||
'札幌市' + // designated city (locality), Sapporo-shi | ||
'北二十四条西四丁目' + // chome/ward (street) | ||
'2番12号'; // "bango" (block and building number) | ||
|
||
t.equal(generator(doc, 'JPN'), expected); | ||
t.end(); | ||
}); | ||
|
||
test('address outside of a designated city', function(t) { | ||
const doc = { | ||
name: { default: '1059-2 大崎' }, | ||
layer: 'address', | ||
housenumber: '1059-2', | ||
street: '大崎', | ||
county: ['小郡市'], | ||
region: ['福岡'], | ||
region_a: ['FO'], | ||
country: ['日本'], | ||
country_a: ['JPN'], | ||
continent: ['アジア'], | ||
}; | ||
|
||
const expected = '' + // no postalcode for this record | ||
'福岡' + // prefecture (region), Fukuoka Prefecture | ||
'小郡市' + // city (county), Ogori | ||
'大崎' + // chome/ward (street), Osaki | ||
'1059番2号'; // "bango" (block and building number) | ||
t.equal(generator(doc, 'JPN'), expected); | ||
t.end(); | ||
}); | ||
|
||
test('neighbourhood admin area', function(t) { | ||
const doc = { | ||
name: { default: '9丁目' }, | ||
layer: 'neighbourhood', | ||
neighbourhood: ['9丁目'], | ||
locality: ['世田谷区'], | ||
county: ['世田谷区'], | ||
region: ['東京'], | ||
region_a: ['TK'], | ||
country: ['日本'], | ||
country_a: ['JPN'], | ||
continent: ['アジア'], | ||
}; | ||
|
||
const expected = '東京' + // prefecture (region), Tokyo | ||
'世田谷区' + // city (county), Setagaya | ||
'世田谷区' + // designated city (locality), Setagaya | ||
'9丁目'; // ward (neighbourhoood) | ||
|
||
t.equal(generator(doc, 'JPN'), expected); | ||
t.end(); | ||
}); | ||
}; | ||
|
||
module.exports.all = function (tape, common) { | ||
function test(name, testFunction) { | ||
return tape('label generator (JPN, 日本ese language): ' + name, testFunction); | ||
} | ||
|
||
for( let testCase in module.exports.tests ){ | ||
module.exports.tests[testCase](test, common); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters