diff --git a/modules/operations/copy.js b/modules/operations/copy.js index 6a4248a0d..d3bfa1c76 100644 --- a/modules/operations/copy.js +++ b/modules/operations/copy.js @@ -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'; } diff --git a/modules/operations/delete.js b/modules/operations/delete.js index 43238eaaf..9f711dab6 100644 --- a/modules/operations/delete.js +++ b/modules/operations/delete.js @@ -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() { diff --git a/modules/operations/disconnect.js b/modules/operations/disconnect.js index 55a8106f7..8f71731b1 100644 --- a/modules/operations/disconnect.js +++ b/modules/operations/disconnect.js @@ -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 = []; diff --git a/modules/operations/move.js b/modules/operations/move.js index 3a25f264c..800064cf6 100644 --- a/modules/operations/move.js +++ b/modules/operations/move.js @@ -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() { diff --git a/modules/operations/reflect.js b/modules/operations/reflect.js index 36ffa554f..9be80cfb9 100644 --- a/modules/operations/reflect.js +++ b/modules/operations/reflect.js @@ -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() { diff --git a/modules/operations/rotate.js b/modules/operations/rotate.js index 7fdf9c4c0..245945486 100644 --- a/modules/operations/rotate.js +++ b/modules/operations/rotate.js @@ -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() { diff --git a/modules/operations/straighten.js b/modules/operations/straighten.js index ae2e744dd..f1829c15d 100644 --- a/modules/operations/straighten.js +++ b/modules/operations/straighten.js @@ -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'; diff --git a/modules/ui/fields/address.js b/modules/ui/fields/address.js index 998393f33..6564e1f2b 100644 --- a/modules/ui/fields/address.js +++ b/modules/ui/fields/address.js @@ -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()); } diff --git a/modules/ui/fields/combo.js b/modules/ui/fields/combo.js index 6ef3c51be..a76fb3981 100644 --- a/modules/ui/fields/combo.js +++ b/modules/ui/fields/combo.js @@ -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()); } diff --git a/modules/ui/fields/input.js b/modules/ui/fields/input.js index 5e7069d42..3f231cb17 100644 --- a/modules/ui/fields/input.js +++ b/modules/ui/fields/input.js @@ -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'); diff --git a/modules/ui/fields/localized.js b/modules/ui/fields/localized.js index c222bc2b3..66f7e3f14 100644 --- a/modules/ui/fields/localized.js +++ b/modules/ui/fields/localized.js @@ -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'); diff --git a/modules/ui/fields/maxspeed.js b/modules/ui/fields/maxspeed.js index 4e5f230b3..982b2eb0f 100644 --- a/modules/ui/fields/maxspeed.js +++ b/modules/ui/fields/maxspeed.js @@ -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()); } diff --git a/modules/util/index.js b/modules/util/index.js index 11358f5b5..d82208a15 100644 --- a/modules/util/index.js +++ b/modules/util/index.js @@ -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'; diff --git a/modules/util/util.js b/modules/util/util.js index e53d52f04..38fbf3803 100644 --- a/modules/util/util.js +++ b/modules/util/util.js @@ -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(''); }