mirror of
https://github.com/FoggedLens/iD.git
synced 2026-02-13 01:02:58 +00:00
Merge pull request #4672 from openstreetmap/1ec5-num-format-3597
Localize numbers, units in scale, info panels
This commit is contained in:
@@ -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
|
||||
@@ -1055,3 +1056,24 @@ en:
|
||||
history: "Toggle history panel"
|
||||
location: "Toggle location panel"
|
||||
measurement: "Toggle measurement panel"
|
||||
units:
|
||||
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"
|
||||
square_meters: "{quantity} m²"
|
||||
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}"
|
||||
|
||||
25
dist/locales/en.json
vendored
25
dist/locales/en.json
vendored
@@ -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",
|
||||
@@ -1221,6 +1222,28 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"units": {
|
||||
"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",
|
||||
"square_meters": "{quantity} m²",
|
||||
"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": {
|
||||
"categories": {
|
||||
"category-barrier": {
|
||||
|
||||
@@ -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 { dmsCoordinatePair } 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: dmsCoordinatePair([loc[1], loc[0]]),
|
||||
location: loc
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,23 +1,12 @@
|
||||
import _debounce from 'lodash-es/debounce';
|
||||
|
||||
import { decimalCoordinatePair, dmsCoordinatePair } 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,13 +21,11 @@ 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);
|
||||
|
||||
list
|
||||
.append('li')
|
||||
.text(coordStr);
|
||||
.text(dmsCoordinatePair(coord))
|
||||
.append('li')
|
||||
.text(decimalCoordinatePair(coord));
|
||||
|
||||
// Location Info
|
||||
selection
|
||||
|
||||
@@ -8,14 +8,15 @@ import {
|
||||
} from 'd3-geo';
|
||||
|
||||
import { t } from '../../util/locale';
|
||||
import { displayArea, displayLength, decimalCoordinatePair, dmsCoordinatePair } from '../../util/units';
|
||||
import { geoExtent } from '../../geo';
|
||||
import { utilDetect } from '../../util/detect';
|
||||
|
||||
|
||||
|
||||
export function uiPanelMeasurement(context) {
|
||||
var isImperial = (utilDetect().locale.toLowerCase() === 'en-us');
|
||||
var OSM_PRECISION = 7;
|
||||
var locale = utilDetect().locale,
|
||||
isImperial = (locale.toLowerCase() === 'en-us');
|
||||
|
||||
|
||||
function radiansToMeters(r) {
|
||||
@@ -51,75 +52,6 @@ export function uiPanelMeasurement(context) {
|
||||
}
|
||||
|
||||
|
||||
function displayLength(m) {
|
||||
var d = m * (isImperial ? 3.28084 : 1),
|
||||
p, unit;
|
||||
|
||||
if (isImperial) {
|
||||
if (d >= 5280) {
|
||||
d /= 5280;
|
||||
unit = 'mi';
|
||||
} else {
|
||||
unit = 'ft';
|
||||
}
|
||||
} else {
|
||||
if (d >= 1000) {
|
||||
d /= 1000;
|
||||
unit = 'km';
|
||||
} else {
|
||||
unit = 'm';
|
||||
}
|
||||
}
|
||||
|
||||
// drop unnecessary precision
|
||||
p = d > 1000 ? 0 : d > 100 ? 1 : 2;
|
||||
|
||||
return String(d.toFixed(p)) + ' ' + unit;
|
||||
}
|
||||
|
||||
|
||||
function displayArea(m2) {
|
||||
var d = m2 * (isImperial ? 10.7639111056 : 1),
|
||||
d1, d2, p1, p2, unit1, unit2;
|
||||
|
||||
if (isImperial) {
|
||||
if (d >= 6969600) { // > 0.25mi² show mi²
|
||||
d1 = d / 27878400;
|
||||
unit1 = 'mi²';
|
||||
} else {
|
||||
d1 = d;
|
||||
unit1 = 'ft²';
|
||||
}
|
||||
|
||||
if (d > 4356 && d < 43560000) { // 0.1 - 1000 acres
|
||||
d2 = d / 43560;
|
||||
unit2 = 'ac';
|
||||
}
|
||||
|
||||
} else {
|
||||
if (d >= 250000) { // > 0.25km² show km²
|
||||
d1 = d / 1000000;
|
||||
unit1 = 'km²';
|
||||
} else {
|
||||
d1 = d;
|
||||
unit1 = 'm²';
|
||||
}
|
||||
|
||||
if (d > 1000 && d < 10000000) { // 0.1 - 1000 hectares
|
||||
d2 = d / 10000;
|
||||
unit2 = 'ha';
|
||||
}
|
||||
}
|
||||
|
||||
// drop unnecessary precision
|
||||
p1 = d1 > 1000 ? 0 : d1 > 100 ? 1 : 2;
|
||||
p2 = d2 > 1000 ? 0 : d2 > 100 ? 1 : 2;
|
||||
|
||||
return String(d1.toFixed(p1)) + ' ' + unit1 +
|
||||
(d2 ? ' (' + String(d2.toFixed(p2)) + ' ' + unit2 + ')' : '');
|
||||
}
|
||||
|
||||
|
||||
function redraw(selection) {
|
||||
var resolver = context.graph();
|
||||
var selected = _filter(context.selectedIDs(), function(e) { return context.hasEntity(e); });
|
||||
@@ -132,7 +64,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;
|
||||
|
||||
@@ -146,16 +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(
|
||||
center[1].toFixed(OSM_PRECISION) + ', ' + center[0].toFixed(OSM_PRECISION)
|
||||
);
|
||||
.text(t('info_panels.measurement.center') + ':');
|
||||
coordItem.append('span')
|
||||
.text(dmsCoordinatePair(center));
|
||||
coordItem.append('span')
|
||||
.text(decimalCoordinatePair(center));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -175,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') {
|
||||
@@ -183,8 +116,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) {
|
||||
@@ -193,7 +125,7 @@ export function uiPanelMeasurement(context) {
|
||||
.append('li')
|
||||
.text(t('info_panels.measurement.area') + ':')
|
||||
.append('span')
|
||||
.text(displayArea(area));
|
||||
.text(displayArea(area, isImperial));
|
||||
}
|
||||
|
||||
|
||||
@@ -201,15 +133,15 @@ export function uiPanelMeasurement(context) {
|
||||
.append('li')
|
||||
.text(lengthLabel + ':')
|
||||
.append('span')
|
||||
.text(displayLength(length));
|
||||
.text(displayLength(length, isImperial));
|
||||
|
||||
list
|
||||
coordItem = list
|
||||
.append('li')
|
||||
.text(t('info_panels.measurement.centroid') + ':')
|
||||
.append('span')
|
||||
.text(
|
||||
centroid[1].toFixed(OSM_PRECISION) + ', ' + centroid[0].toFixed(OSM_PRECISION)
|
||||
);
|
||||
.text(t('info_panels.measurement.centroid') + ':');
|
||||
coordItem.append('span')
|
||||
.text(dmsCoordinatePair(centroid));
|
||||
coordItem.append('span')
|
||||
.text(decimalCoordinatePair(centroid));
|
||||
|
||||
var toggle = isImperial ? 'imperial' : 'metric';
|
||||
|
||||
@@ -233,13 +165,13 @@ export function uiPanelMeasurement(context) {
|
||||
.append('span')
|
||||
.text(t('geometry.' + geometry));
|
||||
|
||||
list
|
||||
coordItem = list
|
||||
.append('li')
|
||||
.text(centerLabel + ':')
|
||||
.append('span')
|
||||
.text(
|
||||
center[1].toFixed(OSM_PRECISION) + ', ' + center[0].toFixed(OSM_PRECISION)
|
||||
);
|
||||
.text(centerLabel + ':');
|
||||
coordItem.append('span')
|
||||
.text(dmsCoordinatePair(center));
|
||||
coordItem.append('span')
|
||||
.text(decimalCoordinatePair(center));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { displayLength } from '../util/units';
|
||||
import { geoLonToMeters, geoMetersToLon } from '../geo';
|
||||
import { utilDetect } from '../util/detect';
|
||||
|
||||
@@ -36,21 +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;
|
||||
scale.text = String(scale.dist) + ' mi';
|
||||
} else {
|
||||
scale.text = String(scale.dist) + ' ft';
|
||||
}
|
||||
} else {
|
||||
if (scale.dist >= 1000) {
|
||||
scale.dist /= 1000;
|
||||
scale.text = String(scale.dist) + ' km';
|
||||
} else {
|
||||
scale.text = String(scale.dist) + ' m';
|
||||
}
|
||||
}
|
||||
scale.text = displayLength(scale.dist / conversion, isImperial);
|
||||
|
||||
return scale;
|
||||
}
|
||||
|
||||
155
modules/util/units.js
Normal file
155
modules/util/units.js
Normal file
@@ -0,0 +1,155 @@
|
||||
import { t } from 'locale';
|
||||
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;
|
||||
|
||||
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 })
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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 given coordinate pair in degree-minute-second format.
|
||||
*
|
||||
* @param {Array<Number>} coord longitude and latitude
|
||||
*/
|
||||
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<Number>} 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 })
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user