From 1d8d7a74a36081e9a01d084841e69c6ce6ecba5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Tue, 9 Jan 2018 00:10:19 -0800 Subject: [PATCH 1/7] Made scale legend localizable --- data/core.yaml | 5 +++++ dist/locales/en.json | 6 ++++++ modules/ui/scale.js | 15 +++++++++------ 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/data/core.yaml b/data/core.yaml index 08021a33f..3b0b30914 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -1055,3 +1055,8 @@ en: history: "Toggle history panel" location: "Toggle location panel" measurement: "Toggle measurement panel" + scale: + miles: "{quantity} mi" + feet: "{quantity} ft" + kilometers: "{quantity} km" + meters: "{quantity} m" diff --git a/dist/locales/en.json b/dist/locales/en.json index 976862a90..7aeda0efe 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -1221,6 +1221,12 @@ } } }, + "scale": { + "miles": "{quantity} mi", + "feet": "{quantity} ft", + "kilometers": "{quantity} km", + "meters": "{quantity} m" + }, "presets": { "categories": { "category-barrier": { diff --git a/modules/ui/scale.js b/modules/ui/scale.js index fb7f869c1..11ec0f63b 100644 --- a/modules/ui/scale.js +++ b/modules/ui/scale.js @@ -1,10 +1,12 @@ import { geoLonToMeters, geoMetersToLon } from '../geo'; +import { t } from '../util/locale'; import { utilDetect } from '../util/detect'; export function uiScale(context) { var projection = context.projection, - isImperial = (utilDetect().locale.toLowerCase() === 'en-us'), + locale = utilDetect().locale, + isImperial = (locale.toLowerCase() === 'en-us'), maxLength = 180, tickHeight = 8; @@ -14,7 +16,7 @@ export function uiScale(context) { conversion = (isImperial ? 3.28084 : 1), dist = geoLonToMeters(loc2[0] - loc1[0], lat) * conversion, scale = { dist: 0, px: 0, text: '' }, - buckets, i, val, dLon; + buckets, i, val, dLon, textKey; if (isImperial) { buckets = [5280000, 528000, 52800, 5280, 500, 50, 5, 1]; @@ -39,18 +41,19 @@ export function uiScale(context) { if (isImperial) { if (scale.dist >= 5280) { scale.dist /= 5280; - scale.text = String(scale.dist) + ' mi'; + textKey = 'scale.miles'; } else { - scale.text = String(scale.dist) + ' ft'; + textKey = 'scale.feet'; } } else { if (scale.dist >= 1000) { scale.dist /= 1000; - scale.text = String(scale.dist) + ' km'; + textKey = 'scale.kilometers'; } else { - scale.text = String(scale.dist) + ' m'; + textKey = 'scale.meters'; } } + scale.text = t(textKey, { quantity: scale.dist.toLocaleString(locale) }); return scale; } From bc5cbc7dfd724fcee21aa5fbbe74734cf7016430 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Tue, 9 Jan 2018 00:13:49 -0800 Subject: [PATCH 2/7] Generalized unit keys --- data/core.yaml | 2 +- dist/locales/en.json | 2 +- modules/ui/scale.js | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/data/core.yaml b/data/core.yaml index 3b0b30914..4e3c734f5 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -1055,7 +1055,7 @@ en: history: "Toggle history panel" location: "Toggle location panel" measurement: "Toggle measurement panel" - scale: + units: miles: "{quantity} mi" feet: "{quantity} ft" kilometers: "{quantity} km" diff --git a/dist/locales/en.json b/dist/locales/en.json index 7aeda0efe..f36bcb42f 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -1221,7 +1221,7 @@ } } }, - "scale": { + "units": { "miles": "{quantity} mi", "feet": "{quantity} ft", "kilometers": "{quantity} km", diff --git a/modules/ui/scale.js b/modules/ui/scale.js index 11ec0f63b..7693a784a 100644 --- a/modules/ui/scale.js +++ b/modules/ui/scale.js @@ -16,7 +16,7 @@ export function uiScale(context) { conversion = (isImperial ? 3.28084 : 1), dist = geoLonToMeters(loc2[0] - loc1[0], lat) * conversion, scale = { dist: 0, px: 0, text: '' }, - buckets, i, val, dLon, textKey; + buckets, i, val, dLon, unit; if (isImperial) { buckets = [5280000, 528000, 52800, 5280, 500, 50, 5, 1]; @@ -41,19 +41,19 @@ export function uiScale(context) { if (isImperial) { if (scale.dist >= 5280) { scale.dist /= 5280; - textKey = 'scale.miles'; + unit = 'miles'; } else { - textKey = 'scale.feet'; + unit = 'feet'; } } else { if (scale.dist >= 1000) { scale.dist /= 1000; - textKey = 'scale.kilometers'; + unit = 'kilometers'; } else { - textKey = 'scale.meters'; + unit = 'meters'; } } - scale.text = t(textKey, { quantity: scale.dist.toLocaleString(locale) }); + scale.text = t('units.' + unit, { quantity: scale.dist.toLocaleString(locale) }); return scale; } From d75aa7d04a3d86bc5164a50f9a32c6d4bbac079e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Tue, 9 Jan 2018 00:58:58 -0800 Subject: [PATCH 3/7] Internationalized measurement panel --- data/core.yaml | 12 +++++- dist/locales/en.json | 14 +++++-- modules/ui/panels/measurement.js | 67 +++++++++++++++++++------------- 3 files changed, 61 insertions(+), 32 deletions(-) diff --git a/data/core.yaml b/data/core.yaml index 4e3c734f5..b3fdc7399 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -319,6 +319,8 @@ en: metric: Metric imperial: Imperial node_count: Number of nodes + coordinate_pair: "{latitude}, {longitude}" + area_pair: "{area1} ({area2})" geometry: point: point vertex: vertex @@ -1056,7 +1058,13 @@ en: location: "Toggle location panel" measurement: "Toggle measurement panel" units: - miles: "{quantity} mi" feet: "{quantity} ft" - kilometers: "{quantity} km" + miles: "{quantity} mi" + square_feet: "{quantity} sq ft" + square_miles: "{quantity} sq mi" + acres: "{quantity} ac" meters: "{quantity} m" + kilometers: "{quantity} km" + square_meters: "{quantity} m²" + square_kilometers: "{quantity} km²" + hectares: "{quantity} ha" diff --git a/dist/locales/en.json b/dist/locales/en.json index f36bcb42f..24831e3ba 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -398,7 +398,9 @@ "location": "Location", "metric": "Metric", "imperial": "Imperial", - "node_count": "Number of nodes" + "node_count": "Number of nodes", + "coordinate_pair": "{latitude}, {longitude}", + "area_pair": "{area1} ({area2})" } }, "geometry": { @@ -1222,10 +1224,16 @@ } }, "units": { - "miles": "{quantity} mi", "feet": "{quantity} ft", + "miles": "{quantity} mi", + "square_feet": "{quantity} sq ft", + "square_miles": "{quantity} sq mi", + "acres": "{quantity} ac", + "meters": "{quantity} m", "kilometers": "{quantity} km", - "meters": "{quantity} m" + "square_meters": "{quantity} m²", + "square_kilometers": "{quantity} km²", + "hectares": "{quantity} ha" }, "presets": { "categories": { diff --git a/modules/ui/panels/measurement.js b/modules/ui/panels/measurement.js index 48a6546bd..e9ccfa467 100644 --- a/modules/ui/panels/measurement.js +++ b/modules/ui/panels/measurement.js @@ -14,7 +14,8 @@ import { utilDetect } from '../../util/detect'; export function uiPanelMeasurement(context) { - var isImperial = (utilDetect().locale.toLowerCase() === 'en-us'); + var locale = utilDetect().locale, + isImperial = (locale.toLowerCase() === 'en-us'); var OSM_PRECISION = 7; @@ -53,70 +54,77 @@ export function uiPanelMeasurement(context) { function displayLength(m) { var d = m * (isImperial ? 3.28084 : 1), - p, unit; + unit; if (isImperial) { if (d >= 5280) { d /= 5280; - unit = 'mi'; + unit = 'miles'; } else { - unit = 'ft'; + unit = 'feet'; } } else { if (d >= 1000) { d /= 1000; - unit = 'km'; + unit = 'kilometers'; } else { - unit = 'm'; + unit = 'meters'; } } - // drop unnecessary precision - p = d > 1000 ? 0 : d > 100 ? 1 : 2; - - return String(d.toFixed(p)) + ' ' + unit; + return t('units.' + unit, { + quantity: d.toLocaleString(locale, { maximumSignificantDigits: 4 }) + }); } function displayArea(m2) { var d = m2 * (isImperial ? 10.7639111056 : 1), - d1, d2, p1, p2, unit1, unit2; + d1, d2, unit1, unit2, area; if (isImperial) { if (d >= 6969600) { // > 0.25mi² show mi² d1 = d / 27878400; - unit1 = 'mi²'; + unit1 = 'square_miles'; } else { d1 = d; - unit1 = 'ft²'; + unit1 = 'square_feet'; } if (d > 4356 && d < 43560000) { // 0.1 - 1000 acres d2 = d / 43560; - unit2 = 'ac'; + unit2 = 'acres'; } } else { if (d >= 250000) { // > 0.25km² show km² d1 = d / 1000000; - unit1 = 'km²'; + unit1 = 'square_kilometers'; } else { d1 = d; - unit1 = 'm²'; + unit1 = 'square_meters'; } if (d > 1000 && d < 10000000) { // 0.1 - 1000 hectares d2 = d / 10000; - unit2 = 'ha'; + unit2 = 'hectares'; } } - // drop unnecessary precision - p1 = d1 > 1000 ? 0 : d1 > 100 ? 1 : 2; - p2 = d2 > 1000 ? 0 : d2 > 100 ? 1 : 2; + area = t('units.' + unit1, { + quantity: d1.toLocaleString(locale, { maximumSignificantDigits: 4 }) + }); - return String(d1.toFixed(p1)) + ' ' + unit1 + - (d2 ? ' (' + String(d2.toFixed(p2)) + ' ' + unit2 + ')' : ''); + if (d2) { + return t('info_panels.measurement.area_pair', { + area1: area, + area2: t('units.' + unit2, { + quantity: d2.toLocaleString(locale, { maximumSignificantDigits: 2 }) + }) + }); + } else { + return area; + } } @@ -132,7 +140,7 @@ export function uiPanelMeasurement(context) { selection .append('h4') .attr('class', 'measurement-heading') - .text(singular || t('info_panels.measurement.selected', { n: selected.length })); + .text(singular || t('info_panels.measurement.selected', { n: selected.length.toLocaleString(locale) })); if (!selected.length) return; @@ -154,7 +162,10 @@ export function uiPanelMeasurement(context) { .text(t('info_panels.measurement.center') + ':') .append('span') .text( - center[1].toFixed(OSM_PRECISION) + ', ' + center[0].toFixed(OSM_PRECISION) + t('info_panels.measurement.coordinate_pair', { + latitude: center[1].toLocaleString(locale, { maximumFractionDigits: OSM_PRECISION }), + longitude: center[0].toLocaleString(locale, { maximumFractionDigits: OSM_PRECISION }) + }) ); return; } @@ -183,8 +194,7 @@ export function uiPanelMeasurement(context) { .append('li') .text(t('info_panels.measurement.node_count') + ':') .append('span') - .text(nodeCount(feature) - ); + .text(nodeCount(feature).toLocaleString(locale)); } if (closed) { @@ -208,7 +218,10 @@ export function uiPanelMeasurement(context) { .text(t('info_panels.measurement.centroid') + ':') .append('span') .text( - centroid[1].toFixed(OSM_PRECISION) + ', ' + centroid[0].toFixed(OSM_PRECISION) + t('info_panels.measurement.coordinate_pair', { + latitude: centroid[1].toLocaleString(locale, { maximumFractionDigits: OSM_PRECISION }), + longitude: centroid[0].toLocaleString(locale, { maximumFractionDigits: OSM_PRECISION }) + }) ); var toggle = isImperial ? 'imperial' : 'metric'; From a1e0d4fc085fa120636beed692b32592e81771e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Tue, 9 Jan 2018 02:00:44 -0800 Subject: [PATCH 4/7] Consolidated unit formatting into util module --- data/core.yaml | 4 +- dist/locales/en.json | 8 +-- modules/ui/panels/location.js | 17 +----- modules/ui/panels/measurement.js | 100 ++----------------------------- modules/ui/scale.js | 24 ++------ modules/util/units.js | 95 +++++++++++++++++++++++++++++ 6 files changed, 113 insertions(+), 135 deletions(-) create mode 100644 modules/util/units.js diff --git a/data/core.yaml b/data/core.yaml index b3fdc7399..9795047bf 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -319,8 +319,6 @@ en: metric: Metric imperial: Imperial node_count: Number of nodes - coordinate_pair: "{latitude}, {longitude}" - area_pair: "{area1} ({area2})" geometry: point: point vertex: vertex @@ -1068,3 +1066,5 @@ en: square_meters: "{quantity} m²" square_kilometers: "{quantity} km²" hectares: "{quantity} ha" + area_pair: "{area1} ({area2})" + coordinate_pair: "{latitude}, {longitude}" diff --git a/dist/locales/en.json b/dist/locales/en.json index 24831e3ba..7f9170fd3 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -398,9 +398,7 @@ "location": "Location", "metric": "Metric", "imperial": "Imperial", - "node_count": "Number of nodes", - "coordinate_pair": "{latitude}, {longitude}", - "area_pair": "{area1} ({area2})" + "node_count": "Number of nodes" } }, "geometry": { @@ -1233,7 +1231,9 @@ "kilometers": "{quantity} km", "square_meters": "{quantity} m²", "square_kilometers": "{quantity} km²", - "hectares": "{quantity} ha" + "hectares": "{quantity} ha", + "area_pair": "{area1} ({area2})", + "coordinate_pair": "{latitude}, {longitude}" }, "presets": { "categories": { diff --git a/modules/ui/panels/location.js b/modules/ui/panels/location.js index 42bda702e..3a866a5bf 100644 --- a/modules/ui/panels/location.js +++ b/modules/ui/panels/location.js @@ -1,23 +1,12 @@ import _debounce from 'lodash-es/debounce'; +import { displayCoordinatePair } from '../../util/units'; import { t } from '../../util/locale'; import { services } from '../../services'; export function uiPanelLocation(context) { var currLocation = ''; - var OSM_PRECISION = 7; - - - function wrap(x, min, max) { - var d = max - min; - return ((x - min) % d + d) % d + min; - } - - - function clamp(x, min, max) { - return Math.max(min, Math.min(x, max)); - } function redraw(selection) { @@ -32,9 +21,7 @@ export function uiPanelLocation(context) { coord = context.map().center(); } - var coordStr = - clamp(coord[1], -90, 90).toFixed(OSM_PRECISION) + ', ' + - wrap(coord[0], -180, 180).toFixed(OSM_PRECISION); + var coordStr = displayCoordinatePair(coord); list .append('li') diff --git a/modules/ui/panels/measurement.js b/modules/ui/panels/measurement.js index e9ccfa467..4300a55af 100644 --- a/modules/ui/panels/measurement.js +++ b/modules/ui/panels/measurement.js @@ -8,6 +8,7 @@ import { } from 'd3-geo'; import { t } from '../../util/locale'; +import { displayArea, displayLength, displayCoordinatePair } from '../../util/units'; import { geoExtent } from '../../geo'; import { utilDetect } from '../../util/detect'; @@ -16,7 +17,6 @@ import { utilDetect } from '../../util/detect'; export function uiPanelMeasurement(context) { var locale = utilDetect().locale, isImperial = (locale.toLowerCase() === 'en-us'); - var OSM_PRECISION = 7; function radiansToMeters(r) { @@ -52,82 +52,6 @@ export function uiPanelMeasurement(context) { } - function displayLength(m) { - var d = m * (isImperial ? 3.28084 : 1), - unit; - - if (isImperial) { - if (d >= 5280) { - d /= 5280; - unit = 'miles'; - } else { - unit = 'feet'; - } - } else { - if (d >= 1000) { - d /= 1000; - unit = 'kilometers'; - } else { - unit = 'meters'; - } - } - - return t('units.' + unit, { - quantity: d.toLocaleString(locale, { maximumSignificantDigits: 4 }) - }); - } - - - function displayArea(m2) { - var d = m2 * (isImperial ? 10.7639111056 : 1), - d1, d2, unit1, unit2, area; - - if (isImperial) { - if (d >= 6969600) { // > 0.25mi² show mi² - d1 = d / 27878400; - unit1 = 'square_miles'; - } else { - d1 = d; - unit1 = 'square_feet'; - } - - if (d > 4356 && d < 43560000) { // 0.1 - 1000 acres - d2 = d / 43560; - unit2 = 'acres'; - } - - } else { - if (d >= 250000) { // > 0.25km² show km² - d1 = d / 1000000; - unit1 = 'square_kilometers'; - } else { - d1 = d; - unit1 = 'square_meters'; - } - - if (d > 1000 && d < 10000000) { // 0.1 - 1000 hectares - d2 = d / 10000; - unit2 = 'hectares'; - } - } - - area = t('units.' + unit1, { - quantity: d1.toLocaleString(locale, { maximumSignificantDigits: 4 }) - }); - - if (d2) { - return t('info_panels.measurement.area_pair', { - area1: area, - area2: t('units.' + unit2, { - quantity: d2.toLocaleString(locale, { maximumSignificantDigits: 2 }) - }) - }); - } else { - return area; - } - } - - function redraw(selection) { var resolver = context.graph(); var selected = _filter(context.selectedIDs(), function(e) { return context.hasEntity(e); }); @@ -161,12 +85,7 @@ export function uiPanelMeasurement(context) { .append('li') .text(t('info_panels.measurement.center') + ':') .append('span') - .text( - t('info_panels.measurement.coordinate_pair', { - latitude: center[1].toLocaleString(locale, { maximumFractionDigits: OSM_PRECISION }), - longitude: center[0].toLocaleString(locale, { maximumFractionDigits: OSM_PRECISION }) - }) - ); + .text(displayCoordinatePair(center)); return; } @@ -203,7 +122,7 @@ export function uiPanelMeasurement(context) { .append('li') .text(t('info_panels.measurement.area') + ':') .append('span') - .text(displayArea(area)); + .text(displayArea(area, isImperial)); } @@ -211,18 +130,13 @@ export function uiPanelMeasurement(context) { .append('li') .text(lengthLabel + ':') .append('span') - .text(displayLength(length)); + .text(displayLength(length, isImperial)); list .append('li') .text(t('info_panels.measurement.centroid') + ':') .append('span') - .text( - t('info_panels.measurement.coordinate_pair', { - latitude: centroid[1].toLocaleString(locale, { maximumFractionDigits: OSM_PRECISION }), - longitude: centroid[0].toLocaleString(locale, { maximumFractionDigits: OSM_PRECISION }) - }) - ); + .text(displayCoordinatePair(centroid)); var toggle = isImperial ? 'imperial' : 'metric'; @@ -250,9 +164,7 @@ export function uiPanelMeasurement(context) { .append('li') .text(centerLabel + ':') .append('span') - .text( - center[1].toFixed(OSM_PRECISION) + ', ' + center[0].toFixed(OSM_PRECISION) - ); + .text(displayCoordinatePair(center)); } } diff --git a/modules/ui/scale.js b/modules/ui/scale.js index 7693a784a..953dc1f66 100644 --- a/modules/ui/scale.js +++ b/modules/ui/scale.js @@ -1,12 +1,11 @@ +import { displayLength } from '../util/units'; import { geoLonToMeters, geoMetersToLon } from '../geo'; -import { t } from '../util/locale'; import { utilDetect } from '../util/detect'; export function uiScale(context) { var projection = context.projection, - locale = utilDetect().locale, - isImperial = (locale.toLowerCase() === 'en-us'), + isImperial = (utilDetect().locale.toLowerCase() === 'en-us'), maxLength = 180, tickHeight = 8; @@ -16,7 +15,7 @@ export function uiScale(context) { conversion = (isImperial ? 3.28084 : 1), dist = geoLonToMeters(loc2[0] - loc1[0], lat) * conversion, scale = { dist: 0, px: 0, text: '' }, - buckets, i, val, dLon, unit; + buckets, i, val, dLon; if (isImperial) { buckets = [5280000, 528000, 52800, 5280, 500, 50, 5, 1]; @@ -38,22 +37,7 @@ export function uiScale(context) { dLon = geoMetersToLon(scale.dist / conversion, lat); scale.px = Math.round(projection([loc1[0] + dLon, loc1[1]])[0]); - if (isImperial) { - if (scale.dist >= 5280) { - scale.dist /= 5280; - unit = 'miles'; - } else { - unit = 'feet'; - } - } else { - if (scale.dist >= 1000) { - scale.dist /= 1000; - unit = 'kilometers'; - } else { - unit = 'meters'; - } - } - scale.text = t('units.' + unit, { quantity: scale.dist.toLocaleString(locale) }); + scale.text = displayLength(scale.dist / conversion, isImperial); return scale; } diff --git a/modules/util/units.js b/modules/util/units.js new file mode 100644 index 000000000..7ea5a2304 --- /dev/null +++ b/modules/util/units.js @@ -0,0 +1,95 @@ +import { t } from 'locale'; +import { utilDetect } from 'detect'; + +var OSM_PRECISION = 7; +var locale = utilDetect().locale; + +export function displayLength(m, isImperial) { + var d = m * (isImperial ? 3.28084 : 1), + unit; + + if (isImperial) { + if (d >= 5280) { + d /= 5280; + unit = 'miles'; + } else { + unit = 'feet'; + } + } else { + if (d >= 1000) { + d /= 1000; + unit = 'kilometers'; + } else { + unit = 'meters'; + } + } + + return t('units.' + unit, { + quantity: d.toLocaleString(locale, { maximumSignificantDigits: 4 }) + }); +} + +export function displayArea(m2, isImperial) { + var d = m2 * (isImperial ? 10.7639111056 : 1), + d1, d2, unit1, unit2, area; + + if (isImperial) { + if (d >= 6969600) { // > 0.25mi² show mi² + d1 = d / 27878400; + unit1 = 'square_miles'; + } else { + d1 = d; + unit1 = 'square_feet'; + } + + if (d > 4356 && d < 43560000) { // 0.1 - 1000 acres + d2 = d / 43560; + unit2 = 'acres'; + } + + } else { + if (d >= 250000) { // > 0.25km² show km² + d1 = d / 1000000; + unit1 = 'square_kilometers'; + } else { + d1 = d; + unit1 = 'square_meters'; + } + + if (d > 1000 && d < 10000000) { // 0.1 - 1000 hectares + d2 = d / 10000; + unit2 = 'hectares'; + } + } + + area = t('units.' + unit1, { + quantity: d1.toLocaleString(locale, { maximumSignificantDigits: 4 }) + }); + + if (d2) { + return t('units.area_pair', { + area1: area, + area2: t('units.' + unit2, { + quantity: d2.toLocaleString(locale, { maximumSignificantDigits: 2 }) + }) + }); + } else { + return area; + } +} + +function wrap(x, min, max) { + var d = max - min; + return ((x - min) % d + d) % d + min; +} + +function clamp(x, min, max) { + return Math.max(min, Math.min(x, max)); +} + +export function displayCoordinatePair(coord) { + return t('units.coordinate_pair', { + latitude: clamp(coord[1], -90, 90).toLocaleString(locale, { maximumFractionDigits: OSM_PRECISION }), + longitude: wrap(coord[0], -180, 180).toLocaleString(locale, { maximumFractionDigits: OSM_PRECISION }) + }); +} From fe8c218fb3bdc390554594ec4eadaf2f955ba4d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Tue, 9 Jan 2018 02:23:13 -0800 Subject: [PATCH 5/7] Localized geocoded coordinate formatting --- modules/ui/feature_list.js | 3 ++- modules/util/units.js | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/modules/ui/feature_list.js b/modules/ui/feature_list.js index d5ed9330b..457940143 100644 --- a/modules/ui/feature_list.js +++ b/modules/ui/feature_list.js @@ -7,6 +7,7 @@ import { d3keybinding as d3_keybinding } from '../lib/d3.keybinding.js'; import * as sexagesimal from '@mapbox/sexagesimal'; import { t } from '../util/locale'; +import { displayCoordinatePair } from '../util/units'; import { geoExtent, geoChooseEdge } from '../geo'; import { modeSelect } from '../modes'; import { osmEntity } from '../osm'; @@ -143,7 +144,7 @@ export function uiFeatureList(context) { id: -1, geometry: 'point', type: t('inspector.location'), - name: loc[0].toFixed(6) + ', ' + loc[1].toFixed(6), + name: displayCoordinatePair([loc[1], loc[0]]), location: loc }); } diff --git a/modules/util/units.js b/modules/util/units.js index 7ea5a2304..c7e2ff1da 100644 --- a/modules/util/units.js +++ b/modules/util/units.js @@ -4,6 +4,12 @@ import { utilDetect } from 'detect'; var OSM_PRECISION = 7; var locale = utilDetect().locale; +/** + * Returns a localized representation of the given length measurement. + * + * @param {Number} m area in meters + * @param {Boolean} isImperial true for U.S. customary units; false for metric + */ export function displayLength(m, isImperial) { var d = m * (isImperial ? 3.28084 : 1), unit; @@ -29,6 +35,12 @@ export function displayLength(m, isImperial) { }); } +/** + * Returns a localized representation of the given area measurement. + * + * @param {Number} m2 area in square meters + * @param {Boolean} isImperial true for U.S. customary units; false for metric + */ export function displayArea(m2, isImperial) { var d = m2 * (isImperial ? 10.7639111056 : 1), d1, d2, unit1, unit2, area; @@ -87,6 +99,11 @@ function clamp(x, min, max) { return Math.max(min, Math.min(x, max)); } +/** + * Returns a human-readable representation of the given coordinate pair. + * + * @param {Array} coord longitude and latitude + */ export function displayCoordinatePair(coord) { return t('units.coordinate_pair', { latitude: clamp(coord[1], -90, 90).toLocaleString(locale, { maximumFractionDigits: OSM_PRECISION }), From 702e3d2a90e67b7e6ff314f4fd840ef0e2a89881 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Tue, 9 Jan 2018 03:25:55 -0800 Subject: [PATCH 6/7] DMS coordinates --- data/core.yaml | 8 ++++++ dist/locales/en.json | 8 ++++++ modules/ui/feature_list.js | 4 +-- modules/ui/panels/location.js | 8 +++--- modules/ui/panels/measurement.js | 33 ++++++++++++--------- modules/util/units.js | 49 ++++++++++++++++++++++++++++++-- 6 files changed, 88 insertions(+), 22 deletions(-) diff --git a/data/core.yaml b/data/core.yaml index 9795047bf..bfcbc11f6 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -1067,4 +1067,12 @@ en: square_kilometers: "{quantity} km²" hectares: "{quantity} ha" area_pair: "{area1} ({area2})" + arcdegrees: "{quantity}°" + arcminutes: "{quantity}′" + arcseconds: "{quantity}″" + north: "N" + south: "S" + east: "E" + west: "W" + coordinate: "{coordinate}{direction}" coordinate_pair: "{latitude}, {longitude}" diff --git a/dist/locales/en.json b/dist/locales/en.json index 7f9170fd3..b17e1411c 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -1233,6 +1233,14 @@ "square_kilometers": "{quantity} km²", "hectares": "{quantity} ha", "area_pair": "{area1} ({area2})", + "arcdegrees": "{quantity}°", + "arcminutes": "{quantity}′", + "arcseconds": "{quantity}″", + "north": "N", + "south": "S", + "east": "E", + "west": "W", + "coordinate": "{coordinate}{direction}", "coordinate_pair": "{latitude}, {longitude}" }, "presets": { diff --git a/modules/ui/feature_list.js b/modules/ui/feature_list.js index 457940143..f0e2e5a3b 100644 --- a/modules/ui/feature_list.js +++ b/modules/ui/feature_list.js @@ -7,7 +7,7 @@ import { d3keybinding as d3_keybinding } from '../lib/d3.keybinding.js'; import * as sexagesimal from '@mapbox/sexagesimal'; import { t } from '../util/locale'; -import { displayCoordinatePair } from '../util/units'; +import { dmsCoordinatePair } from '../util/units'; import { geoExtent, geoChooseEdge } from '../geo'; import { modeSelect } from '../modes'; import { osmEntity } from '../osm'; @@ -144,7 +144,7 @@ export function uiFeatureList(context) { id: -1, geometry: 'point', type: t('inspector.location'), - name: displayCoordinatePair([loc[1], loc[0]]), + name: dmsCoordinatePair([loc[1], loc[0]]), location: loc }); } diff --git a/modules/ui/panels/location.js b/modules/ui/panels/location.js index 3a866a5bf..e79903c11 100644 --- a/modules/ui/panels/location.js +++ b/modules/ui/panels/location.js @@ -1,6 +1,6 @@ import _debounce from 'lodash-es/debounce'; -import { displayCoordinatePair } from '../../util/units'; +import { decimalCoordinatePair, dmsCoordinatePair } from '../../util/units'; import { t } from '../../util/locale'; import { services } from '../../services'; @@ -21,11 +21,11 @@ export function uiPanelLocation(context) { coord = context.map().center(); } - var coordStr = displayCoordinatePair(coord); - list .append('li') - .text(coordStr); + .text(dmsCoordinatePair(coord)) + .append('li') + .text(decimalCoordinatePair(coord)); // Location Info selection diff --git a/modules/ui/panels/measurement.js b/modules/ui/panels/measurement.js index 4300a55af..a8d269cd7 100644 --- a/modules/ui/panels/measurement.js +++ b/modules/ui/panels/measurement.js @@ -8,7 +8,7 @@ import { } from 'd3-geo'; import { t } from '../../util/locale'; -import { displayArea, displayLength, displayCoordinatePair } from '../../util/units'; +import { displayArea, displayLength, decimalCoordinatePair, dmsCoordinatePair } from '../../util/units'; import { geoExtent } from '../../geo'; import { utilDetect } from '../../util/detect'; @@ -78,14 +78,17 @@ export function uiPanelMeasurement(context) { var list = selection .append('ul'); + var coordItem; // multiple features, just display extent center.. if (!singular) { - list + coordItem = list .append('li') - .text(t('info_panels.measurement.center') + ':') - .append('span') - .text(displayCoordinatePair(center)); + .text(t('info_panels.measurement.center') + ':'); + coordItem.append('span') + .text(dmsCoordinatePair(center)); + coordItem.append('span') + .text(decimalCoordinatePair(center)); return; } @@ -132,11 +135,13 @@ export function uiPanelMeasurement(context) { .append('span') .text(displayLength(length, isImperial)); - list + coordItem = list .append('li') - .text(t('info_panels.measurement.centroid') + ':') - .append('span') - .text(displayCoordinatePair(centroid)); + .text(t('info_panels.measurement.centroid') + ':'); + coordItem.append('span') + .text(dmsCoordinatePair(centroid)); + coordItem.append('span') + .text(decimalCoordinatePair(centroid)); var toggle = isImperial ? 'imperial' : 'metric'; @@ -160,11 +165,13 @@ export function uiPanelMeasurement(context) { .append('span') .text(t('geometry.' + geometry)); - list + coordItem = list .append('li') - .text(centerLabel + ':') - .append('span') - .text(displayCoordinatePair(center)); + .text(centerLabel + ':'); + coordItem.append('span') + .text(dmsCoordinatePair(center)); + coordItem.append('span') + .text(decimalCoordinatePair(center)); } } diff --git a/modules/util/units.js b/modules/util/units.js index c7e2ff1da..b27e7c4b7 100644 --- a/modules/util/units.js +++ b/modules/util/units.js @@ -99,13 +99,56 @@ function clamp(x, min, max) { return Math.max(min, Math.min(x, max)); } +function displayCoordinate(deg, pos, neg) { + var min = (Math.abs(deg) - Math.floor(Math.abs(deg))) * 60, + sec = (min - Math.floor(min)) * 60, + displayDegrees = t('units.arcdegrees', { + quantity: Math.floor(Math.abs(deg)).toLocaleString(locale) + }), + displayCoordinate; + + if (Math.floor(sec) > 0) { + displayCoordinate = displayDegrees + + t('units.arcminutes', { quantity: Math.floor(min).toLocaleString(locale) }) + + t('units.arcseconds', { quantity: Math.round(sec).toLocaleString(locale) }); + } else if (Math.floor(min) > 0) { + displayCoordinate = displayDegrees + + t('units.arcminutes', { quantity: Math.round(min).toLocaleString(locale) }); + } else { + displayCoordinate = t('units.arcdegrees', { + quantity: Math.round(Math.abs(deg)).toLocaleString(locale) + }); + } + + if (deg === 0) { + return displayCoordinate; + } else { + return t('units.coordinate', { + coordinate: displayCoordinate, + direction: t('units.' + (deg > 0 ? pos : neg)) + }); + } +} + /** - * Returns a human-readable representation of the given coordinate pair. + * Returns given coordinate pair in degree-minute-second format. * * @param {Array} coord longitude and latitude */ -export function displayCoordinatePair(coord) { - return t('units.coordinate_pair', { +export function dmsCoordinatePair(coord) { + return t('units.coordinate_pair', { + latitude: displayCoordinate(clamp(coord[1], -90, 90), 'north', 'south'), + longitude: displayCoordinate(wrap(coord[0], -180, 180), 'east', 'west') + }); +} + +/** + * Returns the given coordinate pair in decimal format. + * + * @param {Array} coord longitude and latitude + */ +export function decimalCoordinatePair(coord) { + return t('units.coordinate_pair', { latitude: clamp(coord[1], -90, 90).toLocaleString(locale, { maximumFractionDigits: OSM_PRECISION }), longitude: wrap(coord[0], -180, 180).toLocaleString(locale, { maximumFractionDigits: OSM_PRECISION }) }); From ea7339f49a3427f6c2bbd9311319da48204bf30d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Tue, 9 Jan 2018 03:30:14 -0800 Subject: [PATCH 7/7] Fixed geometry type word order MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In many languages, the word for “closed” would follow the word for “line” or “area”, not precede it. Additionally, the word for “closed” may differ depending on what it modifies. --- data/core.yaml | 3 ++- dist/locales/en.json | 3 ++- modules/ui/panels/measurement.js | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/data/core.yaml b/data/core.yaml index bfcbc11f6..0e102c74f 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -309,7 +309,8 @@ en: title: Measurement selected: "{n} selected" geometry: Geometry - closed: closed + closed_line: closed line + closed_area: closed area center: Center perimeter: Perimeter length: Length diff --git a/dist/locales/en.json b/dist/locales/en.json index b17e1411c..df1ee9e9e 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -389,7 +389,8 @@ "title": "Measurement", "selected": "{n} selected", "geometry": "Geometry", - "closed": "closed", + "closed_line": "closed line", + "closed_area": "closed area", "center": "Center", "perimeter": "Perimeter", "length": "Length", diff --git a/modules/ui/panels/measurement.js b/modules/ui/panels/measurement.js index a8d269cd7..ff7369925 100644 --- a/modules/ui/panels/measurement.js +++ b/modules/ui/panels/measurement.js @@ -108,7 +108,7 @@ export function uiPanelMeasurement(context) { .text(t('info_panels.measurement.geometry') + ':') .append('span') .text( - (closed ? t('info_panels.measurement.closed') + ' ' : '') + t('geometry.' + geometry) + closed ? t('info_panels.measurement.closed_' + geometry) : t('geometry.' + geometry) ); if (entity.type !== 'relation') {