diff --git a/js/id/presets.js b/js/id/presets.js index 832b95f7c..c1d5090f9 100644 --- a/js/id/presets.js +++ b/js/id/presets.js @@ -11,6 +11,37 @@ iD.presets = function() { other, other_area; + // Index of presets by (geometry, tag key). + var index = { + point: {}, + vertex: {}, + line: {}, + area: {}, + relation: {} + }; + + all.match = function(entity, resolver) { + var geometry = entity.geometry(resolver), + geometryMatches = index[geometry], + best = -1, + match = geometry === 'area' ? other_area : other; + + for (var k in entity.tags) { + var keyMatches = geometryMatches[k]; + if (!keyMatches) continue; + + for (var i = 0; i < keyMatches.length; i++) { + var score = keyMatches[i].matchScore(entity); + if (score > best) { + best = score; + match = keyMatches[i]; + } + } + } + + return match; + }; + all.load = function(d) { if (d.fields) { @@ -45,6 +76,18 @@ iD.presets = function() { other = all.item('other'); other_area = all.item('other_area'); + for (var i = 0; i < all.collection.length; i++) { + var preset = all.collection[i], + geometry = preset.geometry; + + for (var j = 0; j < geometry.length; j++) { + var g = index[geometry[j]]; + for (var k in preset.tags) { + (g[k] = g[k] || []).push(preset); + } + } + } + return all; }; diff --git a/js/id/presets/collection.js b/js/id/presets/collection.js index 8087fd861..9459d8efb 100644 --- a/js/id/presets/collection.js +++ b/js/id/presets/collection.js @@ -10,32 +10,12 @@ iD.presets.Collection = function(collection) { }); }, - match: function(entity, resolver) { - return presets.matchGeometry(entity.geometry(resolver)).matchTags(entity); - }, - matchGeometry: function(geometry) { return iD.presets.Collection(collection.filter(function(d) { return d.matchGeometry(geometry); })); }, - matchTags: function(entity) { - - var best = -1, - match; - - for (var i = 0; i < collection.length; i++) { - var score = collection[i].matchScore(entity); - if (score > best) { - best = score; - match = collection[i]; - } - } - - return match; - }, - search: function(value) { if (!value) return this; diff --git a/test/index.html b/test/index.html index f7142be05..bb376d036 100644 --- a/test/index.html +++ b/test/index.html @@ -246,6 +246,7 @@ + diff --git a/test/index_packaged.html b/test/index_packaged.html index af2741700..f4a1a9145 100644 --- a/test/index_packaged.html +++ b/test/index_packaged.html @@ -87,6 +87,7 @@ + diff --git a/test/spec/presets.js b/test/spec/presets.js new file mode 100644 index 000000000..f6ffcf706 --- /dev/null +++ b/test/spec/presets.js @@ -0,0 +1,38 @@ +describe("iD.presets", function() { + var p = { + other: { + tags: {}, + geometry: ['point', 'vertex', 'line', 'area'] + }, + residential: { + tags: { + highway: 'residential' + }, + geometry: ['line'] + }, + park: { + tags: { + leisure: 'park' + }, + geometry: ['point', 'area'] + } + }; + + var c = iD.presets().load({presets: p}), + w = iD.Way({tags: { highway: 'residential'}}), + g = iD.Graph().replace(w); + + describe("#match", function() { + it("returns a collection containing presets matching a geometry and tags", function() { + var way = iD.Way({tags: { highway: 'residential'}}), + graph = iD.Graph([way]); + expect(c.match(way, graph).id).to.eql('residential'); + }); + + it("returns an other preset when no tags match", function() { + var way = iD.Way({tags: {foo: 'bar'}}), + graph = iD.Graph([way]); + expect(c.match(way, graph).id).to.eql('other'); + }); + }); +}); diff --git a/test/spec/presets/collection.js b/test/spec/presets/collection.js index 8bfb8d416..2c86d499a 100644 --- a/test/spec/presets/collection.js +++ b/test/spec/presets/collection.js @@ -36,12 +36,6 @@ describe("iD.presets.Collection", function() { }); }); - describe("#matchTags", function() { - it("returns a new collection only containing presets matching an entity's tags", function() { - expect(c.matchTags(w, g)).to.eql(p.residential); - }); - }); - describe("#search", function() { it("filters presets by name", function() { expect(c.search("resid").collection.indexOf(p.residential) >= 0).to.eql(true);