Skip to content

Adding translator class to handle multiple languages #2131

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

Merged
merged 4 commits into from
Dec 19, 2023
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
19 changes: 19 additions & 0 deletions src/lang/languages/en-US.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"distancetool": {
"start": "Start",
"units": {
"mile": " mi",
"feet": " ft",
"kilometer": " km",
"meter": " m"
}
},
"areatool": {
"units": {
"mile": " mi²",
"feet": " ft²",
"kilometer": " km²",
"meter": " m²"
}
}
}
19 changes: 19 additions & 0 deletions src/lang/languages/es-MX.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"distancetool": {
"start": "Inicio",
"units": {
"mile": " mi",
"feet": " ft",
"kilometer": " km",
"meter": " m"
}
},
"areatool": {
"units": {
"mile": " mi²",
"feet": " ft²",
"kilometer": " km²",
"meter": " m²"
}
}
}
19 changes: 19 additions & 0 deletions src/lang/languages/zh-CN.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"distancetool": {
"start": "起点",
"units": {
"mile": " 米",
"feet": " 公里",
"kilometer": " 英尺",
"meter": " 英里"
}
},
"areatool": {
"units": {
"mile": " 平方英里",
"feet": " 平方英尺",
"kilometer": " 平方公里",
"meter": " 平方米"
}
}
}
86 changes: 86 additions & 0 deletions src/lang/translator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import Class from '../core/Class';

import zhCn from '../lang/languages/zh-CN.json';
import esMX from '../lang/languages/es-MX.json';
import enUS from '../lang/languages/en-US.json';

/**
* Maptalks text's language
*/
export class TranslatorError extends Error {
constructor(msg) {
super('Translator: ' + msg);
this.name = 'TranslatorError';
}
}

class Translator extends Class {
constructor(lang) {
super();

this.languages = {
'zh-CN': zhCn,
'es-MX': esMX,
'en-US': enUS
};
this.nodes = {};
this.setLang(lang || 'zh-CN');
}

/**
* Method to update the language of maptalks
* @param {string} lang - Available Langs (zh-CN, en-US, es-MX)
* @example setLang('zh-CN')
*/
setLang(lang) {
const newLanguageNodes = this.languages[lang];
if (!newLanguageNodes) throw new TranslatorError('Setted Lang does not exist');
this.nodes = newLanguageNodes;
}

_validateNestedProps(nestedProps) {
nestedProps.forEach(p => {
if (p === '') throw new TranslatorError('Any of sides of a dot "." cannot be empty');
});
}
/**
* method to return the text of the current language available on lang json's
* @param {string} textNode - Accesible property with the current language text.
* @return {string} Text to show in screen
* @example document.write(translate('areatool.units.kilometer'))
*/
translate(textNode = null) {
if (textNode == null)
throw new TranslatorError('Missing parameter textNode');
if (typeof textNode === 'string') {
let translatedText = null;
if (textNode.includes('.')) {
const nestedProps = textNode.split('.');
if (nestedProps.length > 3) throw new TranslatorError(`Translate function can only access through 3 nested properties, trying to access -> ${nestedProps.length}`);
this._validateNestedProps(nestedProps);

try {
let translatedText = null;
switch (nestedProps.length) {
case 2 :
translatedText = this.nodes[nestedProps[0]][nestedProps[1]];
break;
case 3 :
translatedText = this.nodes[nestedProps[0]][nestedProps[1]][nestedProps[2]];
break;
}
return translatedText;
} catch (err) {
throw new TranslatorError('Unable to find the text translated in lang json' + err.message);
}
} else {
translatedText = this.nodes[textNode];
return translatedText;
}
} else {
throw new TranslatorError('Param passed has to be a String');
}
}
}

export default Translator;
18 changes: 11 additions & 7 deletions src/map/tool/AreaTool.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Size from '../../geo/Size';
import { Geometry, Marker, Label } from '../../geometry';
import DistanceTool from './DistanceTool';
import Translator from '../../lang/translator';

/**
* @property {options} options
Expand All @@ -22,7 +23,8 @@ const options = {
'lineDasharray': '',
'polygonFill': '#ffffff',
'polygonOpacity': 0.5
}
},
'language' : 'zh-CN'
};

/**
Expand Down Expand Up @@ -62,6 +64,7 @@ class AreaTool extends DistanceTool {
super(options);
// this.on('enable', this._afterEnable, this)
// .on('disable', this._afterDisable, this);
this.translator = new Translator(this.options['language']);
this._measureLayers = [];
}

Expand All @@ -74,16 +77,17 @@ class AreaTool extends DistanceTool {
area = map.getProjection().measureArea(toMeasure);
}
this._lastMeasure = area;

const result = this._formatLabelContent(area);
if (result) {
return result;
}
let units;
if (this.options['language'] === 'zh-CN') {
units = [' 平方米', ' 平方公里', ' 平方英尺', ' 平方英里'];
} else {
units = [' sq.m', ' sq.km', ' sq.ft', ' sq.mi'];
}
const units = [
this.translator.translate('areatool.units.meter'),
this.translator.translate('areatool.units.kilometer'),
this.translator.translate('areatool.units.feet'),
this.translator.translate('areatool.units.mile')];

let content = '';
const decimals = this.options['decimalPlaces'];
if (this.options['metric']) {
Expand Down
17 changes: 10 additions & 7 deletions src/map/tool/DistanceTool.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Geometry from '../../geometry/Geometry';
import Marker from '../../geometry/Marker';
import Label from '../../geometry/Label';
import VectorLayer from '../../layer/VectorLayer';
import Translator from '../../lang/translator';
import DrawTool from './DrawTool';

/**
Expand Down Expand Up @@ -113,6 +114,7 @@ class DistanceTool extends DrawTool {
this.on('enable', this._afterEnable, this)
.on('disable', this._afterDisable, this);
this._measureLayers = [];
this.translator = new Translator(this.options['language']);
}

/**
Expand Down Expand Up @@ -196,16 +198,17 @@ class DistanceTool extends DrawTool {
length = map.getProjection().measureLength(toMeasure);
}
this._lastMeasure = length;

const result = this._formatLabelContent(length);
if (result) {
return result;
}
let units;
if (this.options['language'] === 'zh-CN') {
units = [' 米', ' 公里', ' 英尺', ' 英里'];
} else {
units = [' m', ' km', ' feet', ' mile'];
}
const units = [
this.translator.translate('distancetool.units.meter'),
this.translator.translate('distancetool.units.kilometer'),
this.translator.translate('distancetool.units.feet'),
this.translator.translate('distancetool.units.mile')
];
let content = '';
const decimals = this.options['decimalPlaces'];
if (this.options['metric']) {
Expand Down Expand Up @@ -266,7 +269,7 @@ class DistanceTool extends DrawTool {
});
//调用_setPrjCoordinates主要是为了解决repeatworld下,让它能标注在其他世界的问题
marker._setPrjCoordinates(prjCoord);
const content = (this.options['language'] === 'zh-CN' ? '起点' : 'start');
const content = this.translator.translate('distancetool.start');
const startLabel = new Label(content, param['coordinate'], this.options['labelOptions']);
startLabel._setPrjCoordinates(prjCoord);
this._lastVertex = startLabel;
Expand Down