From 9f58f1fb5c7239789ca3500dba6473e5b8237f87 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Thu, 5 Aug 2021 12:45:39 -0400 Subject: [PATCH] Improve code for focusing a validation issue on a relation The "center" of the issue might be a spot of map that doesn't contain the relation. This code chooses a piece of the relation that has been downloaded and focuses on that. --- modules/core/validator.js | 46 ++++++++++++++++++++++++++++++++------- modules/util/index.js | 3 ++- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/modules/core/validator.js b/modules/core/validator.js index 4f328fd1b..114fb971a 100644 --- a/modules/core/validator.js +++ b/modules/core/validator.js @@ -4,7 +4,7 @@ import { prefs } from './preferences'; import { coreDifference } from './difference'; import { geoExtent } from '../geo/extent'; import { modeSelect } from '../modes/select'; -import { utilArrayChunk, utilArrayGroupBy, utilRebind } from '../util'; +import { utilArrayChunk, utilArrayGroupBy, utilEntityAndDeepMemberIDs, utilRebind } from '../util'; import * as Validations from '../validations/index'; @@ -262,17 +262,47 @@ export function coreValidator(context) { // `issue` - the issue to focus on // validator.focusIssue = (issue) => { - const extent = issue.extent(context.graph()); - if (!extent) return; + const graph = context.graph(); + let selectID; + let focusCenter; - const setZoom = Math.max(context.map().zoom(), 19); - context.map().unobscuredCenterZoomEase(extent.center(), setZoom); + // Try to focus the map at the center of the issue.. + const issueExtent = issue.extent(graph); + if (issueExtent) { + focusCenter = issueExtent.center(); + } - // select the first entity + // Try to select the first entity in the issue.. if (issue.entityIds && issue.entityIds.length) { + selectID = issue.entityIds[0]; + + // If a relation, focus on one of its members instead. + // Otherwise we might be focusing on a part of map where the relation is not visible. + if (selectID && selectID.charAt(0) === 'r') { // relation + const ids = utilEntityAndDeepMemberIDs([selectID], graph); + let nodeID = ids.find(id => id.charAt(0) === 'n' && graph.hasEntity(id)); + + if (!nodeID) { // relation has no downloaded nodes to focus on + const wayID = ids.find(id => id.charAt(0) === 'w' && graph.hasEntity(id)); + if (wayID) { + nodeID = graph.entity(wayID).first(); // focus on the first node of this way + } + } + + if (nodeID) { + focusCenter = graph.entity(nodeID).loc; + } + } + } + + if (focusCenter) { // Adjust the view + const setZoom = Math.max(context.map().zoom(), 19); + context.map().unobscuredCenterZoomEase(focusCenter, setZoom); + } + + if (selectID) { // Enter select mode window.setTimeout(() => { - let ids = issue.entityIds; - context.enter(modeSelect(context, [ids[0]])); + context.enter(modeSelect(context, [selectID])); dispatch.call('focusedIssue', this, issue); }, 250); // after ease } diff --git a/modules/util/index.js b/modules/util/index.js index 683c476c2..3c0836aed 100644 --- a/modules/util/index.js +++ b/modules/util/index.js @@ -22,9 +22,10 @@ export { utilDisplayType } from './util'; export { utilDisplayLabel } from './util'; export { utilEntityRoot } from './util'; export { utilEditDistance } from './util'; -export { utilEntitySelector } from './util'; +export { utilEntityAndDeepMemberIDs } from './util'; export { utilEntityOrMemberSelector } from './util'; export { utilEntityOrDeepMemberSelector } from './util'; +export { utilEntitySelector } from './util'; export { utilFastMouse } from './util'; export { utilFetchJson } from './util'; export { utilFunctor } from './util';