Add a reusable function for calculating the combined extent of multiple entities (re: #7706)

This commit is contained in:
Quincy Morgan
2020-06-16 13:17:43 -04:00
parent f53cce783a
commit 5f93da5a59
14 changed files with 44 additions and 72 deletions

View File

@@ -3,8 +3,7 @@ import { event as d3_event } from 'd3-selection';
import { t } from '../core/localizer';
import { behaviorOperation } from '../behavior/operation';
import { uiCmd } from '../ui/cmd';
import { geoExtent } from '../geo';
import { utilArrayGroupBy, utilGetAllNodes } from '../util';
import { utilArrayGroupBy, utilTotalExtent } from '../util';
export function operationCopy(context, selectedIDs) {
@@ -109,10 +108,7 @@ export function operationCopy(context, selectedIDs) {
operation.disabled = function() {
var nodes = utilGetAllNodes(getFilteredIdsToCopy(), context.graph());
var extent = nodes.reduce(function(extent, node) {
return extent.extend(node.extent(context.graph()));
}, geoExtent());
var extent = utilTotalExtent(getFilteredIdsToCopy(), context.graph());
if (extent.percentContainedIn(context.map().extent()) < 0.8) {
return 'too_large';
}

View File

@@ -1,11 +1,11 @@
import { t } from '../core/localizer';
import { actionDeleteMultiple } from '../actions/delete_multiple';
import { behaviorOperation } from '../behavior/operation';
import { geoExtent, geoSphericalDistance } from '../geo';
import { geoSphericalDistance } from '../geo';
import { modeBrowse } from '../modes/browse';
import { modeSelect } from '../modes/select';
import { uiCmd } from '../ui/cmd';
import { utilGetAllNodes } from '../util';
import { utilGetAllNodes, utilTotalExtent } from '../util';
export function operationDelete(context, selectedIDs) {
@@ -13,9 +13,7 @@ export function operationDelete(context, selectedIDs) {
var action = actionDeleteMultiple(selectedIDs);
var nodes = utilGetAllNodes(selectedIDs, context.graph());
var coords = nodes.map(function(n) { return n.loc; });
var extent = nodes.reduce(function(extent, node) {
return extent.extend(node.extent(context.graph()));
}, geoExtent());
var extent = utilTotalExtent(selectedIDs, context.graph());
var operation = function() {

View File

@@ -1,8 +1,7 @@
import { t } from '../core/localizer';
import { actionDisconnect } from '../actions/disconnect';
import { behaviorOperation } from '../behavior/operation';
import { geoExtent } from '../geo';
import { utilGetAllNodes } from '../util/index';
import { utilGetAllNodes, utilTotalExtent } from '../util/util';
export function operationDisconnect(context, selectedIDs) {
@@ -28,9 +27,7 @@ export function operationDisconnect(context, selectedIDs) {
// At the selected vertices, disconnect the selected ways, if any, else
// disconnect all connected ways
_extent = _vertexIDs.reduce(function(extent, id) {
return extent.extend(context.entity(id).extent(context.graph()));
}, geoExtent());
_extent = utilTotalExtent(_vertexIDs, context.graph());
_vertexIDs.forEach(function(vertexID) {
var action = actionDisconnect(vertexID);
@@ -61,9 +58,7 @@ export function operationDisconnect(context, selectedIDs) {
});
_nodes = utilGetAllNodes(_wayIDs, context.graph());
_coords = _nodes.map(function(n) { return n.loc; });
_extent = ways.reduce(function(extent, entity) {
return extent.extend(entity.extent(context.graph()));
}, geoExtent());
_extent = utilTotalExtent(ways, context.graph());
// actions for connected nodes shared by at least two selected ways
var sharedActions = [];

View File

@@ -1,17 +1,14 @@
import { t } from '../core/localizer';
import { behaviorOperation } from '../behavior/operation';
import { geoExtent } from '../geo';
import { modeMove } from '../modes/move';
import { utilGetAllNodes } from '../util';
import { utilGetAllNodes, utilTotalExtent } from '../util/util';
export function operationMove(context, selectedIDs) {
var multi = (selectedIDs.length === 1 ? 'single' : 'multiple');
var nodes = utilGetAllNodes(selectedIDs, context.graph());
var coords = nodes.map(function(n) { return n.loc; });
var extent = nodes.reduce(function(extent, node) {
return extent.extend(node.extent(context.graph()));
}, geoExtent());
var extent = utilTotalExtent(selectedIDs, context.graph());
var operation = function() {

View File

@@ -1,8 +1,7 @@
import { t } from '../core/localizer';
import { actionReflect } from '../actions/reflect';
import { behaviorOperation } from '../behavior/operation';
import { geoExtent } from '../geo';
import { utilGetAllNodes } from '../util';
import { utilGetAllNodes, utilTotalExtent } from '../util/util';
export function operationReflectShort(context, selectedIDs) {
@@ -20,9 +19,7 @@ export function operationReflect(context, selectedIDs, axis) {
var multi = (selectedIDs.length === 1 ? 'single' : 'multiple');
var nodes = utilGetAllNodes(selectedIDs, context.graph());
var coords = nodes.map(function(n) { return n.loc; });
var extent = nodes.reduce(function(extent, node) {
return extent.extend(node.extent(context.graph()));
}, geoExtent());
var extent = utilTotalExtent(selectedIDs, context.graph());
var operation = function() {

View File

@@ -1,17 +1,14 @@
import { t } from '../core/localizer';
import { behaviorOperation } from '../behavior/operation';
import { geoExtent } from '../geo';
import { modeRotate } from '../modes/rotate';
import { utilGetAllNodes } from '../util';
import { utilGetAllNodes, utilTotalExtent } from '../util/util';
export function operationRotate(context, selectedIDs) {
var multi = (selectedIDs.length === 1 ? 'single' : 'multiple');
var nodes = utilGetAllNodes(selectedIDs, context.graph());
var coords = nodes.map(function(n) { return n.loc; });
var extent = nodes.reduce(function(extent, node) {
return extent.extend(node.extent(context.graph()));
}, geoExtent());
var extent = utilTotalExtent(selectedIDs, context.graph());
var operation = function() {

View File

@@ -2,8 +2,7 @@ import { t } from '../core/localizer';
import { actionStraightenNodes } from '../actions/straighten_nodes';
import { actionStraightenWay } from '../actions/straighten_way';
import { behaviorOperation } from '../behavior/operation';
import { geoExtent } from '../geo';
import { utilArrayDifference, utilGetAllNodes } from '../util/index';
import { utilArrayDifference, utilGetAllNodes, utilTotalExtent } from '../util/index';
export function operationStraighten(context, selectedIDs) {
@@ -13,9 +12,7 @@ export function operationStraighten(context, selectedIDs) {
var _nodes = utilGetAllNodes(selectedIDs, context.graph());
var _coords = _nodes.map(function(n) { return n.loc; });
var _extent = _nodes.reduce(function(extent, node) {
return extent.extend(node.extent(context.graph()));
}, geoExtent());
var _extent = utilTotalExtent(selectedIDs, context.graph());
var _action = chooseAction();
var _geometry;
@@ -67,9 +64,7 @@ export function operationStraighten(context, selectedIDs) {
if (_nodeIDs.length) {
// If we're only straightenting between two points, we only need that extent visible
_extent = utilGetAllNodes(_nodeIDs, context.graph()).reduce(function(extent, node) {
return extent.extend(node.extent(context.graph()));
}, geoExtent());
_extent = utilTotalExtent(_nodeIDs, context.graph());
}
_geometry = _wayIDs.length === 1 ? 'line' : 'lines';

View File

@@ -6,7 +6,7 @@ import { presetManager } from '../../presets';
import { fileFetcher } from '../../core/file_fetcher';
import { geoExtent, geoChooseEdge, geoSphericalDistance } from '../../geo';
import { uiCombobox } from '../combobox';
import { utilArrayUniqBy, utilGetSetValue, utilNoAuto, utilRebind } from '../../util';
import { utilArrayUniqBy, utilGetSetValue, utilNoAuto, utilRebind, utilTotalExtent } from '../../util';
import { t } from '../../core/localizer';
@@ -302,10 +302,7 @@ export function uiFieldAddress(field, context) {
function combinedEntityExtent() {
return _entityIDs && _entityIDs.length && _entityIDs.reduce(function(extent, entityID) {
var entity = context.graph().entity(entityID);
return extent.extend(entity.extent(context.graph()));
}, geoExtent());
return _entityIDs && _entityIDs.length && utilTotalExtent(_entityIDs, context.graph());
}

View File

@@ -4,12 +4,11 @@ import { drag as d3_drag } from 'd3-drag';
import * as countryCoder from '@ideditor/country-coder';
import { fileFetcher } from '../../core/file_fetcher';
import { geoExtent } from '../../geo';
import { osmEntity } from '../../osm/entity';
import { t } from '../../core/localizer';
import { services } from '../../services';
import { uiCombobox } from '../combobox';
import { utilArrayUniq, utilGetSetValue, utilNoAuto, utilRebind, utilUnicodeCharsCount } from '../../util';
import { utilArrayUniq, utilGetSetValue, utilNoAuto, utilRebind, utilTotalExtent, utilUnicodeCharsCount } from '../../util';
export {
uiFieldCombo as uiFieldMultiCombo,
@@ -691,10 +690,7 @@ export function uiFieldCombo(field, context) {
function combinedEntityExtent() {
return _entityIDs && _entityIDs.length && _entityIDs.reduce(function(extent, entityID) {
var entity = context.graph().entity(entityID);
return extent.extend(entity.extent(context.graph()));
}, geoExtent());
return _entityIDs && _entityIDs.length && utilTotalExtent(_entityIDs, context.graph());
}

View File

@@ -5,8 +5,7 @@ import * as countryCoder from '@ideditor/country-coder';
import { presetManager } from '../../presets';
import { fileFetcher } from '../../core/file_fetcher';
import { t, localizer } from '../../core/localizer';
import { geoExtent } from '../../geo';
import { utilGetSetValue, utilNoAuto, utilRebind } from '../../util';
import { utilGetSetValue, utilNoAuto, utilRebind, utilTotalExtent } from '../../util';
import { svgIcon } from '../../svg/icon';
export {
@@ -219,10 +218,7 @@ export function uiFieldText(field, context) {
};
function combinedEntityExtent() {
return _entityIDs && _entityIDs.length && _entityIDs.reduce(function(extent, entityID) {
var entity = context.graph().entity(entityID);
return extent.extend(entity.extent(context.graph()));
}, geoExtent());
return _entityIDs && _entityIDs.length && utilTotalExtent(_entityIDs, context.graph());
}
return utilRebind(i, dispatch, 'on');

View File

@@ -5,12 +5,11 @@ import * as countryCoder from '@ideditor/country-coder';
import { presetManager } from '../../presets';
import { fileFetcher } from '../../core/file_fetcher';
import { t, localizer } from '../../core/localizer';
import { geoExtent } from '../../geo';
import { services } from '../../services';
import { svgIcon } from '../../svg';
import { uiTooltip } from '../tooltip';
import { uiCombobox } from '../combobox';
import { utilArrayUniq, utilEditDistance, utilGetSetValue, utilNoAuto, utilRebind, utilUniqueDomId } from '../../util';
import { utilArrayUniq, utilEditDistance, utilGetSetValue, utilNoAuto, utilRebind, utilTotalExtent, utilUniqueDomId } from '../../util';
var _languagesArray = [];
@@ -649,10 +648,7 @@ export function uiFieldLocalized(field, context) {
}
function combinedEntityExtent() {
return _entityIDs && _entityIDs.length && _entityIDs.reduce(function(extent, entityID) {
var entity = context.graph().entity(entityID);
return extent.extend(entity.extent(context.graph()));
}, geoExtent());
return _entityIDs && _entityIDs.length && utilTotalExtent(_entityIDs, context.graph());
}
return utilRebind(localized, dispatch, 'on');

View File

@@ -2,10 +2,9 @@ import { dispatch as d3_dispatch } from 'd3-dispatch';
import { select as d3_select } from 'd3-selection';
import * as countryCoder from '@ideditor/country-coder';
import { geoExtent } from '../../geo';
import { uiCombobox } from '../combobox';
import { t } from '../../core/localizer';
import { utilGetSetValue, utilNoAuto, utilRebind } from '../../util';
import { utilGetSetValue, utilNoAuto, utilRebind, utilTotalExtent } from '../../util';
export function uiFieldMaxspeed(field, context) {
@@ -146,10 +145,7 @@ export function uiFieldMaxspeed(field, context) {
function combinedEntityExtent() {
return _entityIDs && _entityIDs.length && _entityIDs.reduce(function(extent, entityID) {
var entity = context.graph().entity(entityID);
return extent.extend(entity.extent(context.graph()));
}, geoExtent());
return _entityIDs && _entityIDs.length && utilTotalExtent(_entityIDs, context.graph());
}

View File

@@ -45,6 +45,7 @@ export { utilStringQs } from './util';
export { utilTagDiff } from './util';
export { utilTagText } from './util';
export { utilTiler } from './tiler';
export { utilTotalExtent } from './util';
export { utilTriggerEvent } from './trigger_event';
export { utilUnicodeCharsCount } from './util';
export { utilUnicodeCharsTruncated } from './util';

View File

@@ -5,6 +5,7 @@ import { presetManager } from '../presets';
import { t, localizer } from '../core/localizer';
import { utilArrayUnion } from './array';
import { utilDetect } from './detect';
import { geoExtent } from '../geo/extent';
export function utilTagText(entity) {
@@ -15,6 +16,20 @@ export function utilTagText(entity) {
}
export function utilTotalExtent(array, graph) {
var extent = geoExtent();
var val, entity;
for (var i = 0; i < array.length; i++) {
val = array[i];
entity = typeof val === 'string' ? graph.hasEntity(val) : val;
if (entity) {
extent._extend(entity.extent(graph));
}
}
return extent;
}
export function utilTagDiff(oldTags, newTags) {
var tagDiff = [];
var keys = utilArrayUnion(Object.keys(oldTags), Object.keys(newTags)).sort();
@@ -523,7 +538,7 @@ export function utilUnicodeCharsCount(str) {
}
// Returns a new string representing `str` cut from its start to `limit` length
// in unicode characters. Note that this runs the risk of splitting graphemes.
// in unicode characters. Note that this runs the risk of splitting graphemes.
export function utilUnicodeCharsTruncated(str, limit) {
return Array.from(str).slice(0, limit).join('');
}