From 5b4aa529de8983f1797f10f96df0930695b368b3 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Wed, 27 Mar 2019 02:43:25 -0400 Subject: [PATCH] Replace lodash uniq (re: 6087) --- modules/actions/circularize.js | 7 ++-- modules/actions/connect.js | 11 +++--- modules/actions/delete_relation.js | 19 +++++----- modules/actions/delete_way.js | 27 +++++++-------- modules/actions/merge.js | 18 +++++----- modules/actions/reflect.js | 54 +++++++++++++---------------- modules/core/history.js | 15 ++++---- modules/core/validator.js | 5 ++- modules/modes/select.js | 13 +++---- modules/operations/circularize.js | 16 ++++----- modules/operations/orthogonalize.js | 4 +-- modules/operations/rotate.js | 8 ++--- modules/operations/straighten.js | 4 +-- modules/osm/intersection.js | 14 ++++---- modules/osm/node.js | 4 +-- modules/osm/way.js | 16 +++++---- modules/presets/collection.js | 6 ++-- modules/presets/index.js | 13 ++++--- modules/presets/preset.js | 6 ++-- modules/services/osm.js | 22 +++--------- modules/services/wikidata.js | 9 +++-- modules/svg/defs.js | 6 ++-- modules/ui/fields/combo.js | 14 ++++---- modules/ui/intro/building.js | 7 ++-- modules/ui/intro/intro.js | 8 ++--- modules/ui/shortcuts.js | 5 ++- modules/util/keybinding.js | 11 +++--- 27 files changed, 151 insertions(+), 191 deletions(-) diff --git a/modules/actions/circularize.js b/modules/actions/circularize.js index ab8cf38e4..7f564593a 100644 --- a/modules/actions/circularize.js +++ b/modules/actions/circularize.js @@ -1,5 +1,3 @@ -import _uniq from 'lodash-es/uniq'; - import { median as d3_median } from 'd3-array'; import { @@ -10,6 +8,7 @@ import { import { geoVecInterp, geoVecLength } from '../geo'; import { osmNode } from '../osm'; +import { utilArrayUniq } from '../util'; export function actionCircularize(wayId, projection, maxAngle) { @@ -31,7 +30,7 @@ export function actionCircularize(wayId, projection, maxAngle) { graph = action.makeConvex(graph); } - var nodes = _uniq(graph.childNodes(way)); + var nodes = utilArrayUniq(graph.childNodes(way)); var keyNodes = nodes.filter(function(n) { return graph.parentWays(n).length !== 1; }); var points = nodes.map(function(n) { return projection(n.loc); }); var keyPoints = keyNodes.map(function(n) { return projection(n.loc); }); @@ -193,7 +192,7 @@ export function actionCircularize(wayId, projection, maxAngle) { action.makeConvex = function(graph) { var way = graph.entity(wayId); - var nodes = _uniq(graph.childNodes(way)); + var nodes = utilArrayUniq(graph.childNodes(way)); var points = nodes.map(function(n) { return projection(n.loc); }); var sign = d3_polygonArea(points) > 0 ? 1 : -1; var hull = d3_polygonHull(points); diff --git a/modules/actions/connect.js b/modules/actions/connect.js index 8a3e4891b..47a1b3742 100644 --- a/modules/actions/connect.js +++ b/modules/actions/connect.js @@ -1,6 +1,5 @@ -import _uniq from 'lodash-es/uniq'; - import { actionDeleteNode } from './delete_node'; +import { utilArrayUniq } from '../util'; // Connect the ways at the given nodes. @@ -113,7 +112,7 @@ export function actionConnect(nodeIDs) { // test restrictions - restrictionIDs = _uniq(restrictionIDs); + restrictionIDs = utilArrayUniq(restrictionIDs); for (i = 0; i < restrictionIDs.length; i++) { relation = graph.entity(restrictionIDs[i]); if (!relation.isComplete(graph)) continue; @@ -122,7 +121,7 @@ export function actionConnect(nodeIDs) { .filter(function(m) { return m.type === 'way'; }) .map(function(m) { return graph.entity(m.id); }); - memberWays = _uniq(memberWays); + memberWays = utilArrayUniq(memberWays); var f = relation.memberByRole('from'); var t = relation.memberByRole('to'); var isUturn = (f.id === t.id); @@ -134,8 +133,8 @@ export function actionConnect(nodeIDs) { collectNodes(relation.members[j], nodes); } - nodes.keyfrom = _uniq(nodes.keyfrom.filter(hasDuplicates)); - nodes.keyto = _uniq(nodes.keyto.filter(hasDuplicates)); + nodes.keyfrom = utilArrayUniq(nodes.keyfrom.filter(hasDuplicates)); + nodes.keyto = utilArrayUniq(nodes.keyto.filter(hasDuplicates)); var filter = keyNodeFilter(nodes.keyfrom, nodes.keyto); nodes.from = nodes.from.filter(filter); diff --git a/modules/actions/delete_relation.js b/modules/actions/delete_relation.js index a81b33af1..c9555587b 100644 --- a/modules/actions/delete_relation.js +++ b/modules/actions/delete_relation.js @@ -1,11 +1,9 @@ -import _map from 'lodash-es/map'; -import _uniq from 'lodash-es/uniq'; import { actionDeleteMultiple } from './delete_multiple'; +import { utilArrayUniq } from '../util'; // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteRelationAction.as -export function actionDeleteRelation(relationId) { - +export function actionDeleteRelation(relationID) { function canDeleteEntity(entity, graph) { return !graph.parentWays(entity).length && @@ -15,11 +13,11 @@ export function actionDeleteRelation(relationId) { var action = function(graph) { - var relation = graph.entity(relationId); + var relation = graph.entity(relationID); graph.parentRelations(relation) .forEach(function(parent) { - parent = parent.removeMembersWithID(relationId); + parent = parent.removeMembersWithID(relationID); graph = graph.replace(parent); if (parent.isDegenerate()) { @@ -27,12 +25,13 @@ export function actionDeleteRelation(relationId) { } }); - _uniq(_map(relation.members, 'id')).forEach(function(memberId) { - graph = graph.replace(relation.removeMembersWithID(memberId)); + var memberIDs = utilArrayUniq(relation.members.map(function(m) { return m.id; })); + memberIDs.forEach(function(memberID) { + graph = graph.replace(relation.removeMembersWithID(memberID)); - var entity = graph.entity(memberId); + var entity = graph.entity(memberID); if (canDeleteEntity(entity, graph)) { - graph = actionDeleteMultiple([memberId])(graph); + graph = actionDeleteMultiple([memberID])(graph); } }); diff --git a/modules/actions/delete_way.js b/modules/actions/delete_way.js index 9373e2464..dab4f0981 100644 --- a/modules/actions/delete_way.js +++ b/modules/actions/delete_way.js @@ -1,10 +1,8 @@ -import _uniq from 'lodash-es/uniq'; import { actionDeleteRelation } from './delete_relation'; // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteWayAction.as -export function actionDeleteWay(wayId) { - +export function actionDeleteWay(wayID) { function canDeleteNode(node, graph) { return !graph.parentWays(node).length && @@ -14,22 +12,21 @@ export function actionDeleteWay(wayId) { var action = function(graph) { - var way = graph.entity(wayId); + var way = graph.entity(wayID); - graph.parentRelations(way) - .forEach(function(parent) { - parent = parent.removeMembersWithID(wayId); - graph = graph.replace(parent); + graph.parentRelations(way).forEach(function(parent) { + parent = parent.removeMembersWithID(wayID); + graph = graph.replace(parent); - if (parent.isDegenerate()) { - graph = actionDeleteRelation(parent.id)(graph); - } - }); + if (parent.isDegenerate()) { + graph = actionDeleteRelation(parent.id)(graph); + } + }); - _uniq(way.nodes).forEach(function(nodeId) { - graph = graph.replace(way.removeNode(nodeId)); + (new Set(way.nodes)).forEach(function(nodeID) { + graph = graph.replace(way.removeNode(nodeID)); - var node = graph.entity(nodeId); + var node = graph.entity(nodeID); if (canDeleteNode(node, graph)) { graph = graph.remove(node); } diff --git a/modules/actions/merge.js b/modules/actions/merge.js index 699420d06..2f1e2038c 100644 --- a/modules/actions/merge.js +++ b/modules/actions/merge.js @@ -1,20 +1,21 @@ import _groupBy from 'lodash-es/groupBy'; -import _uniq from 'lodash-es/uniq'; + +import { utilArrayUniq } from '../util'; export function actionMerge(ids) { function groupEntitiesByGeometry(graph) { var entities = ids.map(function(id) { return graph.entity(id); }); - return Object.assign({point: [], area: [], line: [], relation: []}, + return Object.assign({ point: [], area: [], line: [], relation: [] }, _groupBy(entities, function(entity) { return entity.geometry(graph); })); } var action = function(graph) { - var geometries = groupEntitiesByGeometry(graph), - target = geometries.area[0] || geometries.line[0], - points = geometries.point; + var geometries = groupEntitiesByGeometry(graph); + var target = geometries.area[0] || geometries.line[0]; + var points = geometries.point; points.forEach(function(point) { target = target.mergeTags(point.tags); @@ -24,8 +25,8 @@ export function actionMerge(ids) { graph = graph.replace(parent.replaceMember(point, target)); }); - var nodes = _uniq(graph.childNodes(target)), - removeNode = point; + var nodes = utilArrayUniq(graph.childNodes(target)); + var removeNode = point; for (var i = 0; i < nodes.length; i++) { var node = nodes[i]; @@ -55,8 +56,9 @@ export function actionMerge(ids) { var geometries = groupEntitiesByGeometry(graph); if (geometries.point.length === 0 || (geometries.area.length + geometries.line.length) !== 1 || - geometries.relation.length !== 0) + geometries.relation.length !== 0) { return 'not_eligible'; + } }; diff --git a/modules/actions/reflect.js b/modules/actions/reflect.js index be435c5f9..5df28d557 100644 --- a/modules/actions/reflect.js +++ b/modules/actions/reflect.js @@ -3,13 +3,7 @@ import { polygonCentroid as d3_polygonCentroid } from 'd3-polygon'; -import { - geoExtent, - geoRotate, - geoVecInterp, - geoVecLength -} from '../geo'; - +import { geoExtent, geoRotate, geoVecInterp, geoVecLength } from '../geo'; import { utilGetAllNodes } from '../util'; @@ -21,23 +15,23 @@ export function actionReflect(reflectIds, projection) { // http://gis.stackexchange.com/questions/22895/finding-minimum-area-rectangle-for-given-points // http://gis.stackexchange.com/questions/3739/generalisation-strategies-for-building-outlines/3756#3756 function getSmallestSurroundingRectangle(graph, nodes) { - var points = nodes.map(function(n) { return projection(n.loc); }), - hull = d3_polygonHull(points), - centroid = d3_polygonCentroid(hull), - minArea = Infinity, - ssrExtent = [], - ssrAngle = 0, - c1 = hull[0]; + var points = nodes.map(function(n) { return projection(n.loc); }); + var hull = d3_polygonHull(points); + var centroid = d3_polygonCentroid(hull); + var minArea = Infinity; + var ssrExtent = []; + var ssrAngle = 0; + var c1 = hull[0]; for (var i = 0; i <= hull.length - 1; i++) { - var c2 = (i === hull.length - 1) ? hull[0] : hull[i + 1], - angle = Math.atan2(c2[1] - c1[1], c2[0] - c1[0]), - poly = geoRotate(hull, -angle, centroid), - extent = poly.reduce(function(extent, point) { - return extent.extend(geoExtent(point)); - }, geoExtent()), - area = extent.area(); + var c2 = (i === hull.length - 1) ? hull[0] : hull[i + 1]; + var angle = Math.atan2(c2[1] - c1[1], c2[0] - c1[0]); + var poly = geoRotate(hull, -angle, centroid); + var extent = poly.reduce(function(extent, point) { + return extent.extend(geoExtent(point)); + }, geoExtent()); + var area = extent.area(); if (area < minArea) { minArea = area; ssrExtent = extent; @@ -57,17 +51,17 @@ export function actionReflect(reflectIds, projection) { if (t === null || !isFinite(t)) t = 1; t = Math.min(Math.max(+t, 0), 1); - var nodes = utilGetAllNodes(reflectIds, graph), - ssr = getSmallestSurroundingRectangle(graph, nodes); + var nodes = utilGetAllNodes(reflectIds, graph); + var ssr = getSmallestSurroundingRectangle(graph, nodes); // Choose line pq = axis of symmetry. // The shape's surrounding rectangle has 2 axes of symmetry. // Reflect across the longer axis by default. - var p1 = [(ssr.poly[0][0] + ssr.poly[1][0]) / 2, (ssr.poly[0][1] + ssr.poly[1][1]) / 2 ], - q1 = [(ssr.poly[2][0] + ssr.poly[3][0]) / 2, (ssr.poly[2][1] + ssr.poly[3][1]) / 2 ], - p2 = [(ssr.poly[3][0] + ssr.poly[4][0]) / 2, (ssr.poly[3][1] + ssr.poly[4][1]) / 2 ], - q2 = [(ssr.poly[1][0] + ssr.poly[2][0]) / 2, (ssr.poly[1][1] + ssr.poly[2][1]) / 2 ], - p, q; + var p1 = [(ssr.poly[0][0] + ssr.poly[1][0]) / 2, (ssr.poly[0][1] + ssr.poly[1][1]) / 2 ]; + var q1 = [(ssr.poly[2][0] + ssr.poly[3][0]) / 2, (ssr.poly[2][1] + ssr.poly[3][1]) / 2 ]; + var p2 = [(ssr.poly[3][0] + ssr.poly[4][0]) / 2, (ssr.poly[3][1] + ssr.poly[4][1]) / 2 ]; + var q2 = [(ssr.poly[1][0] + ssr.poly[2][0]) / 2, (ssr.poly[1][1] + ssr.poly[2][1]) / 2 ]; + var p, q; var isLong = (geoVecLength(p1, q1) > geoVecLength(p2, q2)); if ((useLongAxis && isLong) || (!useLongAxis && !isLong)) { @@ -100,9 +94,9 @@ export function actionReflect(reflectIds, projection) { }; - action.useLongAxis = function(_) { + action.useLongAxis = function(val) { if (!arguments.length) return useLongAxis; - useLongAxis = _; + useLongAxis = val; return action; }; diff --git a/modules/core/history.js b/modules/core/history.js index 0ead591c7..5598cc623 100644 --- a/modules/core/history.js +++ b/modules/core/history.js @@ -1,11 +1,9 @@ import _cloneDeep from 'lodash-es/cloneDeep'; import _cloneDeepWith from 'lodash-es/cloneDeepWith'; -import _flatten from 'lodash-es/flatten'; import _groupBy from 'lodash-es/groupBy'; import _isEmpty from 'lodash-es/isEmpty'; import _forEach from 'lodash-es/forEach'; import _map from 'lodash-es/map'; -import _uniq from 'lodash-es/uniq'; import { dispatch as d3_dispatch } from 'd3-dispatch'; import { easeLinear as d3_easeLinear } from 'd3-ease'; @@ -16,7 +14,7 @@ import { coreGraph } from './graph'; import { coreTree } from './tree'; import { osmEntity } from '../osm/entity'; import { uiLoading } from '../ui'; -import { utilArrayDifference, utilObjectOmit, utilRebind, utilSessionMutex } from '../util'; +import { utilArrayDifference, utilArrayUnion, utilObjectOmit, utilRebind, utilSessionMutex } from '../util'; export function coreHistory(context) { @@ -391,7 +389,7 @@ export function coreHistory(context) { function customizer(src) { var copy = utilObjectOmit(_cloneDeep(src), ['type', 'user', 'v', 'version', 'visible']); - if (_isEmpty(copy.tags)) { + if (!Object.keys(copy.tags)) { delete copy.tags; } @@ -503,9 +501,12 @@ export function coreHistory(context) { // childnodes that would normally have been downloaded with it.. #2142 if (loadChildNodes) { var osm = context.connection(); - var baseWays = baseEntities.filter(function(e) { return e.type === 'way'; }); - var nodes = _flatten(_uniq(_map(baseWays, 'nodes'))); - var missing = nodes.filter(function(n) { return !_stack[0].graph.hasEntity(n); }); + var baseWays = baseEntities + .filter(function(e) { return e.type === 'way'; }); + var nodeIDs = baseWays + .reduce(function(acc, way) { return utilArrayUnion(acc, way.nodes); }, []); + var missing = nodeIDs + .filter(function(n) { return !_stack[0].graph.hasEntity(n); }); if (!_isEmpty(missing) && osm) { loadComplete = false; diff --git a/modules/core/validator.js b/modules/core/validator.js index fbd5de71a..def1f3e1e 100644 --- a/modules/core/validator.js +++ b/modules/core/validator.js @@ -1,13 +1,12 @@ import _flatten from 'lodash-es/flatten'; import _flattenDeep from 'lodash-es/flattenDeep'; -import _uniq from 'lodash-es/uniq'; import { dispatch as d3_dispatch } from 'd3-dispatch'; import { geoExtent } from '../geo'; import { osmEntity } from '../osm'; import { t } from '../util/locale'; -import { utilRebind } from '../util/rebind'; +import { utilArrayUniq, utilRebind } from '../util'; import * as Validations from '../validations/index'; @@ -177,7 +176,7 @@ export function coreValidator(context) { return validation(changes, context); })); - entitiesToCheck = _uniq(_flattenDeep(entitiesToCheck.map(function(entity) { + entitiesToCheck = utilArrayUniq(_flattenDeep(entitiesToCheck.map(function(entity) { var entities = [entity]; if (entity.type === 'node') { // validate ways if their nodes have changed entities = entities.concat(graph.parentWays(entity)); diff --git a/modules/modes/select.js b/modules/modes/select.js index 11962bbb7..6b10d50c2 100644 --- a/modules/modes/select.js +++ b/modules/modes/select.js @@ -1,6 +1,3 @@ -import _map from 'lodash-es/map'; -import _uniq from 'lodash-es/uniq'; - import { event as d3_event, select as d3_select @@ -27,7 +24,11 @@ import { osmNode, osmWay } from '../osm'; import * as Operations from '../operations/index'; import { uiEditMenu, uiSelectionList } from '../ui'; import { uiCmd } from '../ui/cmd'; -import { utilArrayIntersection, utilEntityOrMemberSelector, utilEntitySelector, utilKeybinding } from '../util'; + +import { + utilArrayIntersection, utilEntityOrMemberSelector, + utilEntitySelector, utilKeybinding +} from '../util'; // deprecation warning - Radial Menu to be removed in iD v3 import { uiRadialMenu } from '../ui'; @@ -100,7 +101,7 @@ export function modeSelect(context, selectedIDs) { return []; // selection includes some not vertexes } - var currParents = _map(graph.parentWays(entity), 'id'); + var currParents = graph.parentWays(entity).map(function(w) { return w.id; }); if (!commonParents.length) { commonParents = currParents; continue; @@ -492,7 +493,7 @@ export function modeSelect(context, selectedIDs) { function nextParent() { d3_event.preventDefault(); - var parents = _uniq(commonParents()); + var parents = commonParents(); if (!parents || parents.length < 2) return; var index = parents.indexOf(_relatedParent); diff --git a/modules/operations/circularize.js b/modules/operations/circularize.js index 5d3b26421..a0ba14bd1 100644 --- a/modules/operations/circularize.js +++ b/modules/operations/circularize.js @@ -1,16 +1,14 @@ -import _uniq from 'lodash-es/uniq'; - import { t } from '../util/locale'; import { actionCircularize } from '../actions'; import { behaviorOperation } from '../behavior'; export function operationCircularize(selectedIDs, context) { - var entityId = selectedIDs[0], - entity = context.entity(entityId), - extent = entity.extent(context.graph()), - geometry = context.geometry(entityId), - action = actionCircularize(entityId, context.projection); + var entityID = selectedIDs[0]; + var entity = context.entity(entityID); + var extent = entity.extent(context.graph()); + var geometry = context.geometry(entityID); + var action = actionCircularize(entityID, context.projection); var operation = function() { @@ -21,7 +19,7 @@ export function operationCircularize(selectedIDs, context) { operation.available = function() { return selectedIDs.length === 1 && entity.type === 'way' && - _uniq(entity.nodes).length > 1; + new Set(entity.nodes).size > 1; }; @@ -29,7 +27,7 @@ export function operationCircularize(selectedIDs, context) { var reason; if (extent.percentContainedIn(context.extent()) < 0.8) { reason = 'too_large'; - } else if (context.hasHiddenConnections(entityId)) { + } else if (context.hasHiddenConnections(entityID)) { reason = 'connected_to_hidden'; } return action.disabled(context.graph()) || reason; diff --git a/modules/operations/orthogonalize.js b/modules/operations/orthogonalize.js index 908ca6071..eec9fee43 100644 --- a/modules/operations/orthogonalize.js +++ b/modules/operations/orthogonalize.js @@ -1,5 +1,3 @@ -import _uniq from 'lodash-es/uniq'; - import { t } from '../util/locale'; import { actionOrthogonalize } from '../actions/index'; import { behaviorOperation } from '../behavior/index'; @@ -20,7 +18,7 @@ export function operationOrthogonalize(selectedIDs, context) { _geometry = context.geometry(_entityID); // square a line/area - if (_entity.type === 'way' && _uniq(_entity.nodes).length > 2 ) { + if (_entity.type === 'way' && new Set(_entity.nodes).size > 2 ) { return actionOrthogonalize(_entityID, context.projection); // square a single vertex diff --git a/modules/operations/rotate.js b/modules/operations/rotate.js index 7236d2f54..442eb1310 100644 --- a/modules/operations/rotate.js +++ b/modules/operations/rotate.js @@ -8,10 +8,10 @@ import { utilGetAllNodes } from '../util'; export function operationRotate(selectedIDs, context) { - var multi = (selectedIDs.length === 1 ? 'single' : 'multiple'), - extent = selectedIDs.reduce(function(extent, id) { - return extent.extend(context.entity(id).extent(context.graph())); - }, geoExtent()); + var multi = (selectedIDs.length === 1 ? 'single' : 'multiple'); + var extent = selectedIDs.reduce(function(extent, id) { + return extent.extend(context.entity(id).extent(context.graph())); + }, geoExtent()); var operation = function() { diff --git a/modules/operations/straighten.js b/modules/operations/straighten.js index bd78388c0..70087c07c 100644 --- a/modules/operations/straighten.js +++ b/modules/operations/straighten.js @@ -1,5 +1,3 @@ -import _uniq from 'lodash-es/uniq'; - import { t } from '../util/locale'; import { actionStraighten } from '../actions/index'; import { behaviorOperation } from '../behavior/index'; @@ -47,7 +45,7 @@ export function operationStraighten(selectedIDs, context) { }); // Return false if line is only 2 nodes long - if (_uniq(nodes).length <= 2) return false; + if (new Set(nodes).size <= 2) return false; // Return false unless exactly 0 or 2 specific start/end nodes are selected if (!(selectedNodes.length === 0 || selectedNodes.length === 2)) return false; diff --git a/modules/osm/intersection.js b/modules/osm/intersection.js index dce7f0600..37f2c23b1 100644 --- a/modules/osm/intersection.js +++ b/modules/osm/intersection.js @@ -1,10 +1,8 @@ -import _uniq from 'lodash-es/uniq'; - import { actionDeleteRelation, actionReverse, actionSplit } from '../actions'; import { coreGraph } from '../core'; import { geoAngle, geoSphericalDistance } from '../geo'; import { osmEntity } from './entity'; -import { utilArrayDifference } from '../util'; +import { utilArrayDifference, utilArrayUniq } from '../util'; export function osmTurn(turn) { @@ -89,7 +87,7 @@ export function osmIntersection(graph, startVertexId, maxDistance) { hasWays = true; // check the way's children for more key vertices - nodes = _uniq(graph.childNodes(way)); + nodes = utilArrayUniq(graph.childNodes(way)); for (j = 0; j < nodes.length; j++) { node = nodes[j]; if (node === vertex) continue; // same thing @@ -120,8 +118,8 @@ export function osmIntersection(graph, startVertexId, maxDistance) { } } - vertices = _uniq(vertices); - ways = _uniq(ways); + vertices = utilArrayUniq(vertices); + ways = utilArrayUniq(ways); // STEP 2: Build a virtual graph containing only the entities in the intersection.. @@ -200,8 +198,8 @@ export function osmIntersection(graph, startVertexId, maxDistance) { ways = ways.concat(parents); }); - vertices = _uniq(vertices); - ways = _uniq(ways); + vertices = utilArrayUniq(vertices); + ways = utilArrayUniq(ways); vertexIds = vertices.map(function(v) { return v.id; }); wayIds = ways.map(function(w) { return w.id; }); diff --git a/modules/osm/node.js b/modules/osm/node.js index 96b7f47f7..ff38afd12 100644 --- a/modules/osm/node.js +++ b/modules/osm/node.js @@ -1,8 +1,8 @@ import _map from 'lodash-es/map'; -import _uniq from 'lodash-es/uniq'; import { osmEntity } from './entity'; import { geoAngle, geoExtent } from '../geo'; +import { utilArrayUniq } from '../util'; export function osmNode() { @@ -141,7 +141,7 @@ Object.assign(osmNode.prototype, { }, this); - return _uniq(results); + return utilArrayUniq(results); }, diff --git a/modules/osm/way.js b/modules/osm/way.js index 4802b074c..2b6c29880 100644 --- a/modules/osm/way.js +++ b/modules/osm/way.js @@ -1,5 +1,4 @@ import _map from 'lodash-es/map'; -import _uniq from 'lodash-es/uniq'; import { geoArea as d3_geoArea } from 'd3-geo'; @@ -8,6 +7,7 @@ import { osmEntity } from './entity'; import { osmLanes } from './lanes'; import { osmOneWayTags, osmRightSideIsInsideTags } from './tags'; import { areaKeys } from '../core/context'; +import { utilArrayUniq } from '../util'; export function osmWay() { @@ -171,8 +171,8 @@ Object.assign(osmWay.prototype, { isConvex: function(resolver) { if (!this.isClosed() || this.isDegenerate()) return null; - var nodes = _uniq(resolver.childNodes(this)); - var coords = _map(nodes, 'loc'); + var nodes = utilArrayUniq(resolver.childNodes(this)); + var coords = nodes.map(function(n) { return n.loc; }); var curr = 0; var prev = 0; @@ -238,7 +238,7 @@ Object.assign(osmWay.prototype, { isDegenerate: function() { - return _uniq(this.nodes).length < (this.isArea() ? 3 : 2); + return (new Set(this.nodes).size < (this.isArea() ? 3 : 2)); }, @@ -435,7 +435,7 @@ Object.assign(osmWay.prototype, { way: { '@id': this.osmId(), '@version': this.version || 0, - nd: _map(this.nodes, function(id) { + nd: this.nodes.map(function(id) { return { keyAttributes: { ref: osmEntity.id.toOSM(id) } }; }), tag: _map(this.tags, function(v, k) { @@ -452,7 +452,9 @@ Object.assign(osmWay.prototype, { asGeoJSON: function(resolver) { return resolver.transient(this, 'GeoJSON', function() { - var coordinates = _map(resolver.childNodes(this), 'loc'); + var coordinates = resolver.childNodes(this) + .map(function(n) { return n.loc; }); + if (this.isArea() && this.isClosed()) { return { type: 'Polygon', @@ -474,7 +476,7 @@ Object.assign(osmWay.prototype, { var json = { type: 'Polygon', - coordinates: [_map(nodes, 'loc')] + coordinates: [ nodes.map(function(n) { return n.loc; }) ] }; if (!this.isClosed() && nodes.length) { diff --git a/modules/presets/collection.js b/modules/presets/collection.js index bb3b82594..8b182798b 100644 --- a/modules/presets/collection.js +++ b/modules/presets/collection.js @@ -1,6 +1,4 @@ -import _uniq from 'lodash-es/uniq'; - -import { utilEditDistance } from '../util/index'; +import { utilArrayUniq, utilEditDistance } from '../util'; export function presetCollection(collection) { @@ -163,7 +161,7 @@ export function presetCollection(collection) { } } - return presetCollection(_uniq(results)); + return presetCollection(utilArrayUniq(results)); } }; diff --git a/modules/presets/index.js b/modules/presets/index.js index 82f22bbfe..a434a20f0 100644 --- a/modules/presets/index.js +++ b/modules/presets/index.js @@ -1,7 +1,5 @@ import _bind from 'lodash-es/bind'; import _forEach from 'lodash-es/forEach'; -import _isEmpty from 'lodash-es/isEmpty'; -import _uniq from 'lodash-es/uniq'; import { dispatch as d3_dispatch } from 'd3-dispatch'; import { json as d3_json } from 'd3-request'; @@ -11,7 +9,7 @@ import { presetCategory } from './category'; import { presetCollection } from './collection'; import { presetField } from './field'; import { presetPreset } from './preset'; -import { utilRebind } from '../util'; +import { utilArrayUniq, utilRebind } from '../util'; export { presetCategory }; export { presetCollection }; @@ -88,7 +86,8 @@ export function presetIndex(context) { all.allowsVertex = function(entity, resolver) { if (entity.type !== 'node') return false; - if (_isEmpty(entity.tags)) return true; + if (Object.keys(entity.tags).length === 0) return true; + return resolver.transient(entity, 'vertexMatch', function() { var vertexPresets = _index.vertex; if (entity.isOnAddressLine(resolver)) { @@ -273,12 +272,12 @@ export function presetIndex(context) { all.defaults = function(geometry, n) { var rec = all.recent().matchGeometry(geometry).collection.slice(0, 4); - var def = _uniq(rec.concat(_defaults[geometry].collection)).slice(0, n - 1); - return presetCollection(_uniq(rec.concat(def).concat(all.fallback(geometry)))); + var def = utilArrayUniq(rec.concat(_defaults[geometry].collection)).slice(0, n - 1); + return presetCollection(utilArrayUniq(rec.concat(def).concat(all.fallback(geometry)))); }; all.recent = function() { - return presetCollection(_uniq(all.getRecents().map(function(d) { + return presetCollection(utilArrayUniq(all.getRecents().map(function(d) { return d.preset; }))); }; diff --git a/modules/presets/preset.js b/modules/presets/preset.js index c6ba50744..0778813a8 100644 --- a/modules/presets/preset.js +++ b/modules/presets/preset.js @@ -1,8 +1,6 @@ -import _uniq from 'lodash-es/uniq'; - import { t } from '../util/locale'; import { areaKeys } from '../core/context'; -import { utilObjectOmit } from '../util'; +import { utilArrayUniq, utilObjectOmit } from '../util'; export function presetPreset(id, preset, fields, visible, rawPresets) { @@ -77,7 +75,7 @@ export function presetPreset(id, preset, fields, visible, rawPresets) { fieldIDs = inheritedFieldIDs(preset.parentPresetID(), prop); } // resolve duplicate fields - fieldIDs = _uniq(fieldIDs); + fieldIDs = utilArrayUniq(fieldIDs); // update this preset with the results preset[prop] = fieldIDs; diff --git a/modules/services/osm.js b/modules/services/osm.js index 8a5a6eb34..c76aa6065 100644 --- a/modules/services/osm.js +++ b/modules/services/osm.js @@ -5,7 +5,6 @@ import _groupBy from 'lodash-es/groupBy'; import _isEmpty from 'lodash-es/isEmpty'; import _map from 'lodash-es/map'; import _throttle from 'lodash-es/throttle'; -import _uniq from 'lodash-es/uniq'; import rbush from 'rbush'; @@ -15,21 +14,8 @@ import { xml as d3_xml } from 'd3-request'; import osmAuth from 'osm-auth'; import { JXON } from '../util/jxon'; import { geoExtent, geoVecAdd } from '../geo'; - -import { - osmEntity, - osmNode, - osmNote, - osmRelation, - osmWay -} from '../osm'; - -import { - utilRebind, - utilIdleWorker, - utilTiler, - utilQsString -} from '../util'; +import { osmEntity, osmNode, osmNote, osmRelation, osmWay } from '../osm'; +import { utilArrayUniq, utilRebind, utilIdleWorker, utilTiler, utilQsString } from '../util'; var tiler = utilTiler(); @@ -526,7 +512,7 @@ export default { loadMultiple: function(ids, callback) { var that = this; - _forEach(_groupBy(_uniq(ids), osmEntity.id.type), function(v, k) { + _forEach(_groupBy(utilArrayUniq(ids), osmEntity.id.type), function(v, k) { var type = k + 's'; var osmIDs = _map(v, osmEntity.id.toOSM); var options = { skipSeen: false }; @@ -622,7 +608,7 @@ export default { var toLoad = []; var cached = []; - _uniq(uids).forEach(function(uid) { + utilArrayUniq(uids).forEach(function(uid) { if (_userCache.user[uid]) { delete _userCache.toLoad[uid]; cached.push(_userCache.user[uid]); diff --git a/modules/services/wikidata.js b/modules/services/wikidata.js index d4df4e6fb..faf50bf5f 100644 --- a/modules/services/wikidata.js +++ b/modules/services/wikidata.js @@ -1,13 +1,12 @@ -import _uniq from 'lodash-es/uniq'; - import { json as d3_json } from 'd3-request'; -import { utilQsString } from '../util'; +import { utilArrayUniq, utilQsString } from '../util'; import { currentLocale } from '../util/locale'; var apibase = 'https://www.wikidata.org/w/api.php?'; var _wikidataCache = {}; + export default { init: function() {}, @@ -58,7 +57,7 @@ export default { return; } - var langs = _uniq([ + var langs = utilArrayUniq([ currentLocale.toLowerCase(), currentLocale.split('-', 2)[0].toLowerCase(), 'en' @@ -145,7 +144,7 @@ export default { if (entity.sitelinks) { // must be one of these that we requested.. - var langs = _uniq([ + var langs = utilArrayUniq([ currentLocale.toLowerCase(), currentLocale.split('-', 2)[0].toLowerCase(), 'en' diff --git a/modules/svg/defs.js b/modules/svg/defs.js index b07509cf7..fa89f04c6 100644 --- a/modules/svg/defs.js +++ b/modules/svg/defs.js @@ -1,8 +1,8 @@ -import _uniq from 'lodash-es/uniq'; - import { request as d3_request } from 'd3-request'; import { select as d3_select } from 'd3-selection'; +import { utilArrayUniq } from '../util'; + /* A standalone SVG element that contains only a `defs` sub-element. To be @@ -181,7 +181,7 @@ export function svgDefs(context) { drawDefs.addSprites = function(selection, ids, overrideColors) { var spritesheets = selection.selectAll('.spritesheet'); var currData = spritesheets.data(); - var data = _uniq(currData.concat(ids)); + var data = utilArrayUniq(currData.concat(ids)); spritesheets .data(data) diff --git a/modules/ui/fields/combo.js b/modules/ui/fields/combo.js index b040f4f99..3e9bd78ab 100644 --- a/modules/ui/fields/combo.js +++ b/modules/ui/fields/combo.js @@ -1,5 +1,4 @@ import _map from 'lodash-es/map'; -import _uniq from 'lodash-es/uniq'; import { dispatch as d3_dispatch } from 'd3-dispatch'; @@ -11,7 +10,7 @@ import { import { t } from '../../util/locale'; import { services } from '../../services'; import { uiCombobox } from '../index'; -import { utilGetSetValue, utilNoAuto, utilRebind } from '../../util'; +import { utilArrayUniq, utilGetSetValue, utilNoAuto, utilRebind } from '../../util'; export { uiFieldCombo as uiFieldMultiCombo, @@ -245,7 +244,7 @@ export function uiFieldCombo(field, context) { if (!vals.length) return; if (isMulti) { - _uniq(vals).forEach(function(v) { + utilArrayUniq(vals).forEach(function(v) { var key = field.key + v; if (_entity) { // don't set a multicombo value to 'yes' if it already has a non-'no' value @@ -260,7 +259,7 @@ export function uiFieldCombo(field, context) { } else if (isSemi) { var arr = _multiData.map(function(d) { return d.key; }); arr = arr.concat(vals); - t[field.key] = _uniq(arr).filter(Boolean).join(';'); + t[field.key] = utilArrayUniq(arr).filter(Boolean).join(';'); } window.setTimeout(function() { input.node().focus(); }, 10); @@ -282,8 +281,9 @@ export function uiFieldCombo(field, context) { } else if (isSemi) { var arr = _multiData.map(function(md) { return md.key === d.key ? null : md.key; - }); - arr = _uniq(arr).filter(Boolean); + }).filter(Boolean); + + arr = utilArrayUniq(arr); t[field.key] = arr.length ? arr.join(';') : undefined; } dispatch.call('change', this, t); @@ -400,7 +400,7 @@ export function uiFieldCombo(field, context) { field.keys = _map(_multiData, 'key'); } else if (isSemi) { - var arr = _uniq((tags[field.key] || '').split(';')).filter(Boolean); + var arr = utilArrayUniq((tags[field.key] || '').split(';')).filter(Boolean); _multiData = arr.map(function(k) { return { key: k, diff --git a/modules/ui/intro/building.js b/modules/ui/intro/building.js index d1ea8299c..883706bfe 100644 --- a/modules/ui/intro/building.js +++ b/modules/ui/intro/building.js @@ -1,5 +1,3 @@ -import _uniq from 'lodash-es/uniq'; - import { dispatch as d3_dispatch } from 'd3-dispatch'; import { @@ -9,7 +7,7 @@ import { import { t, textDirection } from '../../util/locale'; import { modeBrowse, modeSelect } from '../../modes'; -import { utilRebind } from '../../util/rebind'; +import { utilArrayUniq, utilRebind } from '../../util'; import { icon, pad, isMostlySquare, selectMenuItem, transitionTime } from './helper'; @@ -155,7 +153,8 @@ export function uiIntroBuilding(context, reveal) { var graph = context.graph(); var way = context.entity(context.selectedIDs()[0]); var nodes = graph.childNodes(way); - var points = _uniq(nodes).map(function(n) { return context.projection(n.loc); }); + var points = utilArrayUniq(nodes) + .map(function(n) { return context.projection(n.loc); }); if (isMostlySquare(points)) { _houseID = way.id; diff --git a/modules/ui/intro/intro.js b/modules/ui/intro/intro.js index d8013c80b..28e47d04c 100644 --- a/modules/ui/intro/intro.js +++ b/modules/ui/intro/intro.js @@ -1,5 +1,3 @@ -import _uniq from 'lodash-es/uniq'; - import { select as d3_select, selectAll as d3_selectAll @@ -15,7 +13,7 @@ import { osmEntity } from '../../osm/entity'; import { services } from '../../services'; import { svgIcon } from '../../svg/icon'; import { uiCurtain } from '../curtain'; -import { utilArrayDifference } from '../../util'; +import { utilArrayDifference, utilArrayUniq } from '../../util'; import { uiIntroWelcome } from './welcome'; import { uiIntroNavigation } from './navigation'; @@ -143,7 +141,7 @@ export function uiIntro(context) { // Store walkthrough progress.. progress.push(chapter); - context.storage('walkthrough_progress', _uniq(progress).join(';')); + context.storage('walkthrough_progress', utilArrayUniq(progress).join(';')); }); return s; }); @@ -151,7 +149,7 @@ export function uiIntro(context) { chapters[chapters.length - 1].on('startEditing', function() { // Store walkthrough progress.. progress.push('startEditing'); - context.storage('walkthrough_progress', _uniq(progress).join(';')); + context.storage('walkthrough_progress', utilArrayUniq(progress).join(';')); // Store if walkthrough is completed.. var incomplete = utilArrayDifference(chapterFlow, progress); diff --git a/modules/ui/shortcuts.js b/modules/ui/shortcuts.js index 8842d96b8..eadf1bf17 100644 --- a/modules/ui/shortcuts.js +++ b/modules/ui/shortcuts.js @@ -1,5 +1,3 @@ -import _uniq from 'lodash-es/uniq'; - import { select as d3_select, selectAll as d3_selectAll @@ -10,6 +8,7 @@ import { dataShortcuts } from '../../data'; import { svgIcon } from '../svg'; import { uiCmd } from './cmd'; import { uiModal } from './modal'; +import { utilArrayUniq } from '../util'; import { utilDetect } from '../util/detect'; @@ -186,7 +185,7 @@ export function uiShortcuts(context) { return uiCmd.display(s.indexOf('.') !== -1 ? t(s) : s); }); - return _uniq(arr).map(function(s) { + return utilArrayUniq(arr).map(function(s) { return { shortcut: s, separator: d.separator, diff --git a/modules/util/keybinding.js b/modules/util/keybinding.js index 6ca9ab1db..7c3ccf4ae 100644 --- a/modules/util/keybinding.js +++ b/modules/util/keybinding.js @@ -1,11 +1,10 @@ -import _isFunction from 'lodash-es/isFunction'; -import _uniq from 'lodash-es/uniq'; - import { event as d3_event, select as d3_select } from 'd3-selection'; +import { utilArrayUniq } from '../util/index'; + export function utilKeybinding(namespace) { var _keybindings = {}; @@ -126,7 +125,7 @@ export function utilKeybinding(namespace) { // Remove one or more keycode bindings. keybinding.off = function(codes, capture) { - var arr = _uniq([].concat(codes)); + var arr = utilArrayUniq([].concat(codes)); for (var i = 0; i < arr.length; i++) { var id = arr[i] + (capture ? '-capture' : '-bubble'); @@ -138,11 +137,11 @@ export function utilKeybinding(namespace) { // Add one or more keycode bindings. keybinding.on = function(codes, callback, capture) { - if (!_isFunction(callback)) { + if (typeof callback !== 'function') { return keybinding.off(codes, capture); } - var arr = _uniq([].concat(codes)); + var arr = utilArrayUniq([].concat(codes)); for (var i = 0; i < arr.length; i++) { var id = arr[i] + (capture ? '-capture' : '-bubble');