Skip to content

Commit

Permalink
Download some members upon selecting a relation (re: #4903, #6656)
Browse files Browse the repository at this point in the history
  • Loading branch information
quincylvania committed Jul 17, 2019
1 parent b4268a8 commit 7ece70e
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 3 deletions.
68 changes: 68 additions & 0 deletions modules/core/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,74 @@ export function coreContext() {
}
};

context.loadEntities = function(entityIDs, callback) {
var handle = window.requestIdleCallback(function() {
_deferred.delete(handle);
if (connection) {
connection.loadMultiple(entityIDs, loadedMultiple);
}
});
_deferred.add(handle);

function loadedMultiple(err, result) {
if (err || !result) {
afterLoad(callback)(err, result);
return;
}

// `loadMultiple` doesn't fetch child nodes, so we have to fetch them
// manually before merging ways

var unloadedNodeIDs = new Set();
var okayResults = [];
var waitingEntities = [];
result.data.forEach(function(entity) {
var hasUnloaded = false;
if (entity.type === 'way') {
entity.nodes.forEach(function(nodeID) {
if (!context.hasEntity(nodeID)) {
hasUnloaded = true;
// mark that we still need this node
unloadedNodeIDs.add(nodeID);
}
});
}
if (hasUnloaded) {
// don't merge ways with unloaded nodes
waitingEntities.push(entity);
} else {
okayResults.push(entity);
}
});
if (okayResults.length) {
// merge valid results right away
afterLoad(callback)(err, { data: okayResults });
}
if (waitingEntities.length) {
// run a followup request to fetch missing nodes
connection.loadMultiple(Array.from(unloadedNodeIDs), function(err, result) {
if (err || !result) {
afterLoad(callback)(err, result);
return;
}

result.data.forEach(function(entity) {
// mark that we successfully received this node
unloadedNodeIDs.delete(entity.id);
// schedule this node to be merged
waitingEntities.push(entity);
});

// since `loadMultiple` could send multiple requests, wait until all have completed
if (unloadedNodeIDs.size === 0) {
// merge the ways and their nodes all at once
afterLoad(callback)(err, { data: waitingEntities });
}
});
}
}
};

context.zoomToEntity = function(entityID, zoomTo) {
if (zoomTo !== false) {
this.loadEntity(entityID, function(err, result) {
Expand Down
26 changes: 25 additions & 1 deletion modules/modes/select.js
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,33 @@ export function modeSelect(context, selectedIDs) {
return operations;
};

function scheduleMissingMemberDownload() {
var missingMemberIDs = new Set();
selectedIDs.forEach(function(id) {
var entity = context.hasEntity(id);
if (!entity || entity.type !== 'relation') return;

entity.members.forEach(function(member) {
if (!context.hasEntity(member.id)) {
missingMemberIDs.add(member.id);
}
});
});

if (missingMemberIDs.size) {
var missingMemberIDsArray = Array.from(missingMemberIDs)
.slice(0, 450); // limit number of members downloaded at once to avoid blocking iD
context.loadEntities(missingMemberIDsArray);
}
}

mode.enter = function() {
if (!checkSelectedIDs()) return;

// if this selection includes relations, fetch their members
scheduleMissingMemberDownload();

// ensure that selected features are rendered even if they would otherwise be hidden
context.features().forceVisible(selectedIDs);

operations = Object.values(Operations)
Expand Down Expand Up @@ -310,7 +334,7 @@ export function modeSelect(context, selectedIDs) {

function dblclick() {
if (!context.map().withinEditableZoom()) return;

var target = d3_select(d3_event.target);

var datum = target.datum();
Expand Down
6 changes: 4 additions & 2 deletions modules/services/osm.js
Original file line number Diff line number Diff line change
Expand Up @@ -538,8 +538,10 @@ export default {

// Load multiple entities in chunks
// (note: callback may be called multiple times)
// Unlike `loadEntity`, child nodes and members are not fetched
// GET /api/0.6/[nodes|ways|relations]?#parameters
loadMultiple: function(ids, callback) {
var cid = _connectionID;
var that = this;
var groups = utilArrayGroupBy(utilArrayUniq(ids), osmEntity.id.type);

Expand All @@ -551,9 +553,9 @@ export default {
utilArrayChunk(osmIDs, 150).forEach(function(arr) {
that.loadFromAPI(
'/api/0.6/' + type + '?' + type + '=' + arr.join(),
function(err, entities) {
wrapcb(that, function(err, entities) {
if (callback) callback(err, { data: entities });
},
}, cid),
options
);
});
Expand Down
7 changes: 7 additions & 0 deletions modules/ui/raw_member_editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ export function uiRawMemberEditor(context) {
function updateDisclosureContent(selection) {
_contentSelection = selection;

if (selection.empty()) return;

var memberships = [];
var entity = context.entity(_entityID);
entity.members.slice(0, _maxMembers).forEach(function(member, index) {
Expand Down Expand Up @@ -379,6 +381,11 @@ export function uiRawMemberEditor(context) {
})
.content(updateDisclosureContent)
);

context.history().on('merge', function() {
// update the UI in case the merge includes newly-downloaded members
updateDisclosureContent(_contentSelection);
});
}

rawMemberEditor.entityID = function(val) {
Expand Down

0 comments on commit 7ece70e

Please sign in to comment.