mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-17 22:24:49 +02:00
Adjustments to multipolygon preset
* It shouldn't appear as a search result for simple areas. * Changing to another area preset shouldn't remove the type=multipolygon tag. * It shouldn't be preferred to the Building preset, which matches with score 0.5. Fixes #1546.
This commit is contained in:
@@ -4509,8 +4509,11 @@
|
||||
"tags": {
|
||||
"type": "multipolygon"
|
||||
},
|
||||
"removeTags": {},
|
||||
"name": "Multipolygon",
|
||||
"icon": "multipolygon"
|
||||
"icon": "multipolygon",
|
||||
"searchable": false,
|
||||
"matchScore": 0.1
|
||||
},
|
||||
"type/restriction": {
|
||||
"geometry": [
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
"tags": {
|
||||
"type": "multipolygon"
|
||||
},
|
||||
"removeTags": {},
|
||||
"name": "Multipolygon",
|
||||
"icon": "multipolygon"
|
||||
"icon": "multipolygon",
|
||||
"searchable": false,
|
||||
"matchScore": 0.1
|
||||
}
|
||||
@@ -27,6 +27,20 @@
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"addTags": {
|
||||
"description": "Tags that are added when changing to the preset (default is the same value as 'tags')",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"removeTags": {
|
||||
"description": "Tags that are removed when changing to another preset (default is the same value as 'tags')",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"description": "Form fields that are displayed for the preset",
|
||||
"type": "array",
|
||||
@@ -49,6 +63,11 @@
|
||||
"description": "Whether or not the preset will be suggested via search",
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"matchScore": {
|
||||
"description": "The quality score this preset will receive when being compared with other matches (higher is better)",
|
||||
"type": "number",
|
||||
"default": 1.0
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
|
||||
+16
-17
@@ -12,24 +12,21 @@ iD.presets.Preset = function(id, preset, fields) {
|
||||
return preset.geometry.indexOf(geometry) >= 0;
|
||||
};
|
||||
|
||||
var matchScore = preset.matchScore || 1;
|
||||
preset.matchScore = function(entity) {
|
||||
var tags = preset.tags,
|
||||
score = 0;
|
||||
|
||||
for (var t in tags) {
|
||||
if (entity.tags[t] === tags[t]) {
|
||||
if (t === 'area') {
|
||||
// score area tag lower to prevent other/area preset
|
||||
// from being chosen over something more specific
|
||||
score += 0.5;
|
||||
} else {
|
||||
score += 1;
|
||||
}
|
||||
score += matchScore;
|
||||
} else if (tags[t] === '*' && t in entity.tags) {
|
||||
score += 0.5;
|
||||
score += matchScore / 2;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return score;
|
||||
};
|
||||
|
||||
@@ -59,30 +56,32 @@ iD.presets.Preset = function(id, preset, fields) {
|
||||
return reference;
|
||||
};
|
||||
|
||||
var removeTags = preset.removeTags || preset.tags;
|
||||
preset.removeTags = function(tags, geometry) {
|
||||
tags = _.omit(tags, _.keys(preset.tags));
|
||||
tags = _.omit(tags, _.keys(removeTags));
|
||||
|
||||
for (var i in preset.fields) {
|
||||
var field = preset.fields[i];
|
||||
for (var f in preset.fields) {
|
||||
var field = preset.fields[f];
|
||||
if (field.matchGeometry(geometry) && field['default'] === tags[field.key]) {
|
||||
delete tags[field.key];
|
||||
}
|
||||
}
|
||||
return tags;
|
||||
|
||||
return tags;
|
||||
};
|
||||
|
||||
var applyTags = preset.applyTags || preset.tags;
|
||||
preset.applyTags = function(tags, geometry) {
|
||||
tags = _.clone(tags);
|
||||
|
||||
for (var k in preset.tags) {
|
||||
if (preset.tags[k] !== '*') tags[k] = preset.tags[k];
|
||||
for (var k in applyTags) {
|
||||
if (applyTags[k] !== '*') tags[k] = applyTags[k];
|
||||
}
|
||||
|
||||
for (var f in preset.fields) {
|
||||
f = preset.fields[f];
|
||||
if (f.matchGeometry(geometry) && f.key && !tags[f.key] && f['default']) {
|
||||
tags[f.key] = f['default'];
|
||||
var field = preset.fields[f];
|
||||
if (field.matchGeometry(geometry) && field.key && !tags[field.key] && field['default']) {
|
||||
tags[field.key] = field['default'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+62
-62
@@ -1,108 +1,108 @@
|
||||
describe('iD.presets.Preset', function() {
|
||||
|
||||
var fields, p;
|
||||
|
||||
beforeEach(function() {
|
||||
if (!p) {
|
||||
fields = {};
|
||||
var i = 0;
|
||||
for (i in iD.data.presets.fields) {
|
||||
fields[i] = iD.presets.Field(i, iD.data.presets.fields[i]);
|
||||
}
|
||||
p = {};
|
||||
for (i in iD.data.presets.presets) {
|
||||
p[i] = iD.presets.Preset(i, iD.data.presets.presets[i], fields);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var w1 = iD.Way({ tags: {
|
||||
highway: 'motorway'
|
||||
}}),
|
||||
w2 = iD.Way({ tags: {
|
||||
leisure: 'pitch',
|
||||
sport: 'tennis'
|
||||
}}),
|
||||
w3 = iD.Way({ tags: {
|
||||
highway: 'residential'
|
||||
}}),
|
||||
w4 = iD.Way({ tags: {
|
||||
building: 'yep'
|
||||
}}),
|
||||
w5 = iD.Way(),
|
||||
g = iD.Graph().replace(w1).replace(w2);
|
||||
|
||||
|
||||
it("has optional fields", function() {
|
||||
expect(p.point.fields).to.eql([]);
|
||||
var preset = iD.presets.Preset('test', {});
|
||||
expect(preset.fields).to.eql([]);
|
||||
});
|
||||
|
||||
describe('#matchGeometry', function() {
|
||||
var n = iD.Node();
|
||||
var g = iD.Graph().replace(n);
|
||||
|
||||
it("returns false if it doesn't match", function() {
|
||||
expect(p['highway/residential'].matchGeometry('point')).to.equal(false);
|
||||
var preset = iD.presets.Preset('test', {geometry: ['line']});
|
||||
expect(preset.matchGeometry('point')).to.equal(false);
|
||||
});
|
||||
|
||||
it("returns true if it does match", function() {
|
||||
expect(p.point.matchGeometry('point')).to.equal(true);
|
||||
var preset = iD.presets.Preset('test', {geometry: ['point', 'line']});
|
||||
expect(preset.matchGeometry('point')).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#matchScore', function() {
|
||||
it("returns -1 if preset does not match tags", function() {
|
||||
expect(p['highway/residential'].matchScore(w1)).to.equal(-1);
|
||||
var preset = iD.presets.Preset('test', {tags: {foo: 'bar'}}),
|
||||
entity = iD.Way({tags: {highway: 'motorway'}});
|
||||
expect(preset.matchScore(entity)).to.equal(-1);
|
||||
});
|
||||
|
||||
it("returns 0 for fallback presets", function() {
|
||||
expect(p.point.matchScore(w1)).to.equal(0);
|
||||
it("returns the value of the matchScore property when matched", function() {
|
||||
var preset = iD.presets.Preset('test', {tags: {highway: 'motorway'}, matchScore: 0.2}),
|
||||
entity = iD.Way({tags: {highway: 'motorway'}});
|
||||
expect(preset.matchScore(entity)).to.equal(0.2);
|
||||
});
|
||||
|
||||
it("returns the number of matched tags", function() {
|
||||
expect(p['highway/residential'].matchScore(w3)).to.equal(1);
|
||||
expect(p['leisure/pitch/tennis'].matchScore(w2)).to.equal(2);
|
||||
it("defaults to the number of matched tags", function() {
|
||||
var preset = iD.presets.Preset('test', {tags: {highway: 'residential'}}),
|
||||
entity = iD.Way({tags: {highway: 'residential'}});
|
||||
expect(preset.matchScore(entity)).to.equal(1);
|
||||
|
||||
var preset = iD.presets.Preset('test', {tags: {highway: 'service', service: 'alley'}}),
|
||||
entity = iD.Way({tags: {highway: 'service', service: 'alley'}});
|
||||
expect(preset.matchScore(entity)).to.equal(2);
|
||||
});
|
||||
|
||||
it("counts * as a match for any value", function() {
|
||||
expect(p.building.matchScore(w4)).to.equal(0.5);
|
||||
expect(p.building.matchScore(w5)).to.equal(-1);
|
||||
it("counts * as a match for any value with score 0.5", function() {
|
||||
var preset = iD.presets.Preset('test', {tags: {building: '*'}}),
|
||||
entity = iD.Way({tags: {building: 'yep'}});
|
||||
expect(preset.matchScore(entity)).to.equal(0.5);
|
||||
});
|
||||
});
|
||||
|
||||
describe("isFallback", function() {
|
||||
it("returns true if preset has no tags", function() {
|
||||
expect(iD.presets.Preset("area", {name: "Area", tags: {}}).isFallback()).to.equal(true);
|
||||
var preset = iD.presets.Preset("area", {tags: {}});
|
||||
expect(preset.isFallback()).to.equal(true);
|
||||
});
|
||||
|
||||
it("returns false if preset has no tags", function() {
|
||||
expect(p.building.isFallback()).to.equal(false);
|
||||
it("returns false if preset has tags", function() {
|
||||
var preset = iD.presets.Preset("area", {tags: {building: 'yes'}});
|
||||
expect(preset.isFallback()).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#applyTags', function() {
|
||||
it("adds match tags", function() {
|
||||
expect(p['highway/residential'].applyTags({}, 'area')).to.eql({ highway: 'residential' });
|
||||
var preset = iD.presets.Preset('test', {tags: {highway: 'residential'}});
|
||||
expect(preset.applyTags({}, 'area')).to.eql({highway: 'residential'});
|
||||
});
|
||||
|
||||
it("does not add wildcard tags", function() {
|
||||
expect(p.amenity.applyTags({}, 'area')).to.eql({});
|
||||
var preset = iD.presets.Preset('test', {tags: {building: '*'}});
|
||||
expect(preset.applyTags({}, 'area')).to.eql({});
|
||||
});
|
||||
|
||||
it("adds default tags", function() {
|
||||
expect(p['amenity/cafe'].applyTags({}, 'area')).to.eql({ amenity: 'cafe', building: 'yes'});
|
||||
expect(p['amenity/cafe'].applyTags({}, 'point')).to.eql({ amenity: 'cafe' });
|
||||
it("adds default tags of fields with matching geometry", function() {
|
||||
var field = iD.presets.Field('field', {key: 'building', geometry: 'area', default: 'yes'}),
|
||||
preset = iD.presets.Preset('test', {fields: ['field']}, {field: field});
|
||||
expect(preset.applyTags({}, 'area')).to.eql({building: 'yes'});
|
||||
});
|
||||
|
||||
it("adds no default tags of fields with non-matching geometry", function() {
|
||||
var field = iD.presets.Field('field', {key: 'building', geometry: 'area', default: 'yes'}),
|
||||
preset = iD.presets.Preset('test', {fields: ['field']}, {field: field});
|
||||
expect(preset.applyTags({}, 'point')).to.eql({});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#removeTags', function() {
|
||||
it('removes match tags', function() {
|
||||
expect(p['highway/residential'].removeTags({ highway: 'residential' }, 'area')).to.eql({});
|
||||
it('removes tags that match preset tags', function() {
|
||||
var preset = iD.presets.Preset('test', {tags: {highway: 'residential'}});
|
||||
expect(preset.removeTags({highway: 'residential'}, 'area')).to.eql({});
|
||||
});
|
||||
|
||||
it('removes default tags', function() {
|
||||
expect(p['amenity/cafe'].removeTags({ amenity: 'cafe', building: 'yes'}, 'area')).to.eql({});
|
||||
expect(p['amenity/cafe'].removeTags({ amenity: 'cafe', building: 'yep'}, 'area')).to.eql({ building: 'yep'});
|
||||
it('removes tags that match field default tags', function() {
|
||||
var field = iD.presets.Field('field', {key: 'building', geometry: 'area', default: 'yes'}),
|
||||
preset = iD.presets.Preset('test', {fields: ['field']}, {field: field});
|
||||
expect(preset.removeTags({building: 'yes'}, 'area')).to.eql({});
|
||||
});
|
||||
|
||||
it('preserves tags that do not match field default tags', function() {
|
||||
var field = iD.presets.Field('field', {key: 'building', geometry: 'area', default: 'yes'}),
|
||||
preset = iD.presets.Preset('test', {fields: ['field']}, {field: field});
|
||||
expect(preset.removeTags({building: 'yep'}, 'area')).to.eql({ building: 'yep'});
|
||||
});
|
||||
|
||||
it('preserves tags that are not listed in removeTags', function() {
|
||||
var preset = iD.presets.Preset('test', {tags: {a: 'b'}, removeTags: {}});
|
||||
expect(preset.removeTags({a: 'b'}, 'area')).to.eql({a: 'b'});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user