diff --git a/modules/modes/HeightTransferMode.js b/modules/modes/HeightTransferMode.js index e2b8cfaf1..15e3a4cca 100644 --- a/modules/modes/HeightTransferMode.js +++ b/modules/modes/HeightTransferMode.js @@ -197,13 +197,24 @@ export class HeightTransferMode extends AbstractSystem { // plateauID once committed) and calling `_recompute()` -- which re-runs `findCandidates()` // (already excludes this candidate, since `findCandidates` filters against `transferredIDs`) // and emits 'change'. That means there's no need for a second manual emit here. + // The changeset `source` is assembled from the `dataUsed` on each edit's + // annotation (see `EditSystem#_gatherSources`). Without it the transfer + // records no provenance at all -- no `MLIT_PLATEAU`, no `RapiD_Plateau_JP`, + // no `source_ref` -- while accepting a building records all three. + // Same lookup the accept path uses in `UiRapidInspector`. + const rapid = this.context.systems.rapid; + const datasetID = (candidate.plateauFeature.__datasetid__ ?? 'plateauJapan') + .replace('-conflated', ''); + const dataset = rapid?.datasets?.get(datasetID); + const action = actionTransferPlateauTags(candidate.osmFeature.id, tagsToAdd); editor.perform(action); editor.commit({ annotation: { type: action.actionName, plateauID: candidate.plateauFeature.id, - entityID: candidate.osmFeature.id + entityID: candidate.osmFeature.id, + dataUsed: dataset?.dataUsed || [datasetID] }, selectedIDs: [ candidate.osmFeature.id ] }); diff --git a/test/browser/modes/HeightTransferMode.test.js b/test/browser/modes/HeightTransferMode.test.js index c95b7ef2a..8b3c6d368 100644 --- a/test/browser/modes/HeightTransferMode.test.js +++ b/test/browser/modes/HeightTransferMode.test.js @@ -326,6 +326,40 @@ describe('HeightTransferMode', () => { }); + it('apply() records the dataset on the annotation so the changeset gets a source', () => { + // Rapid#45: 建物を追加する経路は annotation に dataUsed を付けるが、タグ転記の + // 経路は付けていなかった。変更セットの source は EditSystem がこの値から + // 組み立てるので、無いと MLIT_PLATEAU も RapiD_Plateau_JP も source_ref も付かない。 + const context = makeContext(); + context.systems.rapid.datasets = new Map([ + ['plateauJapan', { id: 'plateauJapan', dataUsed: ['osmf.jp', 'Plateau Buildings'] }] + ]); + const mode = new Rapid.HeightTransferMode(context); + mode.activate(); + + mode.apply(makeCandidate({ + plateauFeature: { id: 'p1', tags: { height: '12' }, __datasetid__: 'plateauJapan' } + })); + + const annotation = context.systems.editor.commitCalls[0].annotation; + expect(annotation.dataUsed).to.eql(['osmf.jp', 'Plateau Buildings']); + }); + + + it('apply() falls back to the dataset id when the catalog has no entry', () => { + const context = makeContext(); + const mode = new Rapid.HeightTransferMode(context); + mode.activate(); + + mode.apply(makeCandidate({ + plateauFeature: { id: 'p1', tags: { height: '12' }, __datasetid__: 'plateauJapan' } + })); + + const annotation = context.systems.editor.commitCalls[0].annotation; + expect(annotation.dataUsed).to.eql(['plateauJapan']); + }); + + it('apply() fires change exactly once per call', () => { const context = makeContext(); const mode = new Rapid.HeightTransferMode(context);