mapeo-id-bmf
Version:
iD Editor for osm-p2p & mapeo-desktop changed to meet requirements of Bruno Manser Fonds
200 lines (155 loc) • 6.52 kB
JavaScript
import _filter from 'lodash-es/filter';
import { event as d3_event } from 'd3-selection';
import {
geoLength as d3_geoLength,
geoCentroid as d3_geoCentroid
} 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 locale = utilDetect().locale,
isImperial = (locale.toLowerCase() === 'en-us');
function radiansToMeters(r) {
// using WGS84 authalic radius (6371007.1809 m)
return r * 6371007.1809;
}
function steradiansToSqmeters(r) {
// http://gis.stackexchange.com/a/124857/40446
return r / (4 * Math.PI) * 510065621724000;
}
function toLineString(feature) {
if (feature.type === 'LineString') return feature;
var result = { type: 'LineString', coordinates: [] };
if (feature.type === 'Polygon') {
result.coordinates = feature.coordinates[0];
} else if (feature.type === 'MultiPolygon') {
result.coordinates = feature.coordinates[0][0];
}
return result;
}
function nodeCount(feature) {
if (feature.type === 'LineString') return feature.coordinates.length;
if (feature.type === 'Polygon') {
return feature.coordinates[0].length - 1;
}
}
function redraw(selection) {
var resolver = context.graph();
var selected = _filter(context.selectedIDs(), function(e) { return context.hasEntity(e); });
var singular = selected.length === 1 ? selected[0] : null;
var extent = geoExtent();
var entity;
selection.html('');
selection
.append('h4')
.attr('class', 'measurement-heading')
.text(singular || t('info_panels.measurement.selected', { n: selected.length.toLocaleString(locale) }));
if (!selected.length) return;
var center;
for (var i = 0; i < selected.length; i++) {
entity = context.entity(selected[i]);
extent._extend(entity.extent(resolver));
}
center = extent.center();
var list = selection
.append('ul');
var coordItem;
// multiple features, just display extent center..
if (!singular) {
coordItem = list
.append('li')
.text(t('info_panels.measurement.center') + ':');
coordItem.append('span')
.text(dmsCoordinatePair(center));
coordItem.append('span')
.text(decimalCoordinatePair(center));
return;
}
// single feature, display details..
if (!entity) return;
var geometry = entity.geometry(resolver);
if (geometry === 'line' || geometry === 'area') {
var closed = (entity.type === 'relation') || (entity.isClosed() && !entity.isDegenerate()),
feature = entity.asGeoJSON(resolver),
length = radiansToMeters(d3_geoLength(toLineString(feature))),
lengthLabel = t('info_panels.measurement.' + (closed ? 'perimeter' : 'length')),
centroid = d3_geoCentroid(feature);
list
.append('li')
.text(t('info_panels.measurement.geometry') + ':')
.append('span')
.text(
closed ? t('info_panels.measurement.closed_' + geometry) : t('geometry.' + geometry)
);
if (entity.type !== 'relation') {
list
.append('li')
.text(t('info_panels.measurement.node_count') + ':')
.append('span')
.text(nodeCount(feature).toLocaleString(locale));
}
if (closed) {
var area = steradiansToSqmeters(entity.area(resolver));
list
.append('li')
.text(t('info_panels.measurement.area') + ':')
.append('span')
.text(displayArea(area, isImperial));
}
list
.append('li')
.text(lengthLabel + ':')
.append('span')
.text(displayLength(length, isImperial));
coordItem = list
.append('li')
.text(t('info_panels.measurement.centroid') + ':');
coordItem.append('span')
.text(dmsCoordinatePair(centroid));
coordItem.append('span')
.text(decimalCoordinatePair(centroid));
var toggle = isImperial ? 'imperial' : 'metric';
selection
.append('a')
.text(t('info_panels.measurement.' + toggle))
.attr('href', '#')
.attr('class', 'button button-toggle-units')
.on('click', function() {
d3_event.preventDefault();
isImperial = !isImperial;
selection.call(redraw);
});
} else {
var centerLabel = t('info_panels.measurement.' + (entity.type === 'node' ? 'location' : 'center'));
list
.append('li')
.text(t('info_panels.measurement.geometry') + ':')
.append('span')
.text(t('geometry.' + geometry));
coordItem = list
.append('li')
.text(centerLabel + ':');
coordItem.append('span')
.text(dmsCoordinatePair(center));
coordItem.append('span')
.text(decimalCoordinatePair(center));
}
}
var panel = function(selection) {
selection.call(redraw);
context.map()
.on('drawn.info-measurement', function() {
selection.call(redraw);
});
};
panel.off = function() {
context.map()
.on('drawn.info-measurement', null);
};
panel.id = 'measurement';
panel.title = t('info_panels.measurement.title');
panel.key = t('info_panels.measurement.key');
return panel;
}