Skip to content

Commit d51f6a1

Browse files
committed
Allow searching for OSM Notes by their noteID
re: #1389 re: openstreetmap/iD#7618 re: openstreetmap/iD#10062
1 parent 36d27fb commit d51f6a1

File tree

2 files changed

+70
-13
lines changed

2 files changed

+70
-13
lines changed

modules/services/OsmService.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -975,6 +975,23 @@ export class OsmService extends AbstractSystem {
975975
}
976976
}
977977

978+
// Load a single note by id, XML format
979+
// GET /api/0.6/notes/#id
980+
loadNote(noteID, callback) {
981+
const options = { skipSeen: false };
982+
const gotNote = (err, results) => {
983+
if (callback) {
984+
callback(err, { data: results });
985+
}
986+
};
987+
988+
this.loadFromAPI(
989+
`/api/0.6/notes/${noteID}`,
990+
gotNote,
991+
options
992+
);
993+
}
994+
978995

979996
// Create a note
980997
// POST /api/0.6/notes?params

modules/ui/feature_list.js

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export function uiFeatureList(context) {
1313
const editor = context.systems.editor;
1414
const l10n = context.systems.l10n;
1515
const map = context.systems.map;
16+
const osm = context.services.osm;
1617
const nominatim = context.services.nominatim;
1718
const presets = context.systems.presets;
1819

@@ -26,7 +27,7 @@ export function uiFeatureList(context) {
2627

2728
header
2829
.append('h3')
29-
.html(l10n.tHtml('inspector.feature_list'));
30+
.text(l10n.t('inspector.feature_list'));
3031

3132
let searchWrap = selection
3233
.append('div')
@@ -124,17 +125,28 @@ export function uiFeatureList(context) {
124125
});
125126
}
126127

127-
// User typed something that looks like an OSM entity id (node/way/relation)
128-
const idMatch = !locationMatch && q.match(/(?:^|\W)(node|way|relation|[nwr])\W?0*([1-9]\d*)(?:\W|$)/i);
128+
// User typed something that looks like an OSM entity id (node/way/relation/note)
129+
const idMatch = !locationMatch && q.match(/(?:^|\W)(node|way|relation|note|[nwr])\W?0*([1-9]\d*)(?:\W|$)/i);
129130
if (idMatch) {
130-
const entityType = idMatch[1].charAt(0);
131+
const entityType = idMatch[1].charAt(0); // n,w,r
131132
const entityID = idMatch[2];
132-
result.push({
133-
id: entityType + entityID,
134-
geometry: entityType === 'n' ? 'point' : entityType === 'w' ? 'line' : 'relation',
135-
type: l10n.displayType(entityType),
136-
name: entityID
137-
});
133+
134+
if (idMatch[1] === 'note') {
135+
result.push({
136+
id: -1,
137+
noteID: entityID,
138+
geometry: 'note',
139+
type: l10n.t('note.note'),
140+
name: entityID
141+
});
142+
} else {
143+
result.push({
144+
id: entityType + entityID,
145+
geometry: entityType === 'n' ? 'point' : entityType === 'w' ? 'line' : 'relation',
146+
type: l10n.displayType(entityType),
147+
name: entityID
148+
});
149+
}
138150
}
139151

140152
// Search for what the user typed in the local and base graphs
@@ -224,6 +236,13 @@ export function uiFeatureList(context) {
224236
type: l10n.t('inspector.relation'),
225237
name: q
226238
});
239+
result.push({
240+
id: -1,
241+
noteID: q,
242+
geometry: 'note',
243+
type: l10n.t('note.note'),
244+
name: q
245+
});
227246
}
228247

229248
return result;
@@ -248,7 +267,7 @@ export function uiFeatureList(context) {
248267
.attr('class', 'entity-name');
249268

250269
list.selectAll('.no-results-item .entity-name')
251-
.html(l10n.tHtml('geocoder.no_results_worldwide'));
270+
.text(l10n.t('geocoder.no_results_worldwide'));
252271

253272
if (nominatim) {
254273
list.selectAll('.geocode-item')
@@ -261,7 +280,7 @@ export function uiFeatureList(context) {
261280
.attr('class', 'label')
262281
.append('span')
263282
.attr('class', 'entity-name')
264-
.html(l10n.tHtml('geocoder.search'));
283+
.text(l10n.t('geocoder.search'));
265284
}
266285

267286
list.selectAll('.no-results-item')
@@ -342,9 +361,30 @@ export function uiFeatureList(context) {
342361
if (d.location) {
343362
map.centerZoomEase([d.location[1], d.location[0]], 19);
344363

345-
} else if (d.id !== -1) {
364+
} else if (d.id !== -1) { // looks like an OSM ID
346365
utilHighlightEntities([d.id], false, context);
347366
map.selectEntityID(d.id, true); // select and fit , download first if necessary
367+
368+
} else if (osm && d.noteID) {
369+
const selectNote = (note) => {
370+
map.scene.enableLayers('notes');
371+
map.centerZoomEase(note.loc, 19);
372+
const selection = new Map().set(note.id, note);
373+
context.enter('select', { selection: selection });
374+
};
375+
376+
let note = osm.getNote(d.noteID);
377+
if (note) {
378+
selectNote(note);
379+
} else {
380+
osm.loadNote(d.noteID, (err) => {
381+
if (err) return;
382+
note = osm.getNote(d.noteID);
383+
if (note) {
384+
selectNote(note);
385+
}
386+
});
387+
}
348388
}
349389
}
350390

0 commit comments

Comments
 (0)