mirror of
https://github.com/FoggedLens/iD.git
synced 2026-04-02 02:00:34 +02:00
Remove old generated bundles
This commit is contained in:
2209
js/lib/id/actions.js
2209
js/lib/id/actions.js
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2259
js/lib/id/core.js
2259
js/lib/id/core.js
File diff suppressed because it is too large
Load Diff
1569
js/lib/id/geo.js
1569
js/lib/id/geo.js
File diff suppressed because it is too large
Load Diff
1340
js/lib/id/modes.js
1340
js/lib/id/modes.js
File diff suppressed because it is too large
Load Diff
@@ -1,540 +0,0 @@
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
||||
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
||||
(factory((global.iD = global.iD || {}, global.iD.operations = global.iD.operations || {})));
|
||||
}(this, function (exports) { 'use strict';
|
||||
|
||||
function Circularize(selectedIDs, context) {
|
||||
var entityId = selectedIDs[0],
|
||||
entity = context.entity(entityId),
|
||||
extent = entity.extent(context.graph()),
|
||||
geometry = context.geometry(entityId),
|
||||
action = iD.actions.Circularize(entityId, context.projection);
|
||||
|
||||
var operation = function() {
|
||||
var annotation = t('operations.circularize.annotation.' + geometry);
|
||||
context.perform(action, annotation);
|
||||
};
|
||||
|
||||
operation.available = function() {
|
||||
return selectedIDs.length === 1 &&
|
||||
entity.type === 'way' &&
|
||||
_.uniq(entity.nodes).length > 1;
|
||||
};
|
||||
|
||||
operation.disabled = function() {
|
||||
var reason;
|
||||
if (extent.percentContainedIn(context.extent()) < 0.8) {
|
||||
reason = 'too_large';
|
||||
} else if (context.hasHiddenConnections(entityId)) {
|
||||
reason = 'connected_to_hidden';
|
||||
}
|
||||
return action.disabled(context.graph()) || reason;
|
||||
};
|
||||
|
||||
operation.tooltip = function() {
|
||||
var disable = operation.disabled();
|
||||
return disable ?
|
||||
t('operations.circularize.' + disable) :
|
||||
t('operations.circularize.description.' + geometry);
|
||||
};
|
||||
|
||||
operation.id = 'circularize';
|
||||
operation.keys = [t('operations.circularize.key')];
|
||||
operation.title = t('operations.circularize.title');
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
function Continue(selectedIDs, context) {
|
||||
var graph = context.graph(),
|
||||
entities = selectedIDs.map(function(id) { return graph.entity(id); }),
|
||||
geometries = _.extend({line: [], vertex: []},
|
||||
_.groupBy(entities, function(entity) { return entity.geometry(graph); })),
|
||||
vertex = geometries.vertex[0];
|
||||
|
||||
function candidateWays() {
|
||||
return graph.parentWays(vertex).filter(function(parent) {
|
||||
return parent.geometry(graph) === 'line' &&
|
||||
parent.affix(vertex.id) &&
|
||||
(geometries.line.length === 0 || geometries.line[0] === parent);
|
||||
});
|
||||
}
|
||||
|
||||
var operation = function() {
|
||||
var candidate = candidateWays()[0];
|
||||
context.enter(iD.modes.DrawLine(
|
||||
context,
|
||||
candidate.id,
|
||||
context.graph(),
|
||||
candidate.affix(vertex.id)));
|
||||
};
|
||||
|
||||
operation.available = function() {
|
||||
return geometries.vertex.length === 1 && geometries.line.length <= 1 &&
|
||||
!context.features().hasHiddenConnections(vertex, context.graph());
|
||||
};
|
||||
|
||||
operation.disabled = function() {
|
||||
var candidates = candidateWays();
|
||||
if (candidates.length === 0)
|
||||
return 'not_eligible';
|
||||
if (candidates.length > 1)
|
||||
return 'multiple';
|
||||
};
|
||||
|
||||
operation.tooltip = function() {
|
||||
var disable = operation.disabled();
|
||||
return disable ?
|
||||
t('operations.continue.' + disable) :
|
||||
t('operations.continue.description');
|
||||
};
|
||||
|
||||
operation.id = 'continue';
|
||||
operation.keys = [t('operations.continue.key')];
|
||||
operation.title = t('operations.continue.title');
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
function Delete(selectedIDs, context) {
|
||||
var action = iD.actions.DeleteMultiple(selectedIDs);
|
||||
|
||||
var operation = function() {
|
||||
var annotation,
|
||||
nextSelectedID;
|
||||
|
||||
if (selectedIDs.length > 1) {
|
||||
annotation = t('operations.delete.annotation.multiple', {n: selectedIDs.length});
|
||||
|
||||
} else {
|
||||
var id = selectedIDs[0],
|
||||
entity = context.entity(id),
|
||||
geometry = context.geometry(id),
|
||||
parents = context.graph().parentWays(entity),
|
||||
parent = parents[0];
|
||||
|
||||
annotation = t('operations.delete.annotation.' + geometry);
|
||||
|
||||
// Select the next closest node in the way.
|
||||
if (geometry === 'vertex' && parents.length === 1 && parent.nodes.length > 2) {
|
||||
var nodes = parent.nodes,
|
||||
i = nodes.indexOf(id);
|
||||
|
||||
if (i === 0) {
|
||||
i++;
|
||||
} else if (i === nodes.length - 1) {
|
||||
i--;
|
||||
} else {
|
||||
var a = iD.geo.sphericalDistance(entity.loc, context.entity(nodes[i - 1]).loc),
|
||||
b = iD.geo.sphericalDistance(entity.loc, context.entity(nodes[i + 1]).loc);
|
||||
i = a < b ? i - 1 : i + 1;
|
||||
}
|
||||
|
||||
nextSelectedID = nodes[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (nextSelectedID && context.hasEntity(nextSelectedID)) {
|
||||
context.enter(iD.modes.Select(context, [nextSelectedID]));
|
||||
} else {
|
||||
context.enter(iD.modes.Browse(context));
|
||||
}
|
||||
|
||||
context.perform(
|
||||
action,
|
||||
annotation);
|
||||
};
|
||||
|
||||
operation.available = function() {
|
||||
return true;
|
||||
};
|
||||
|
||||
operation.disabled = function() {
|
||||
var reason;
|
||||
if (_.some(selectedIDs, context.hasHiddenConnections)) {
|
||||
reason = 'connected_to_hidden';
|
||||
}
|
||||
return action.disabled(context.graph()) || reason;
|
||||
};
|
||||
|
||||
operation.tooltip = function() {
|
||||
var disable = operation.disabled();
|
||||
return disable ?
|
||||
t('operations.delete.' + disable) :
|
||||
t('operations.delete.description');
|
||||
};
|
||||
|
||||
operation.id = 'delete';
|
||||
operation.keys = [iD.ui.cmd('⌘⌫'), iD.ui.cmd('⌘⌦')];
|
||||
operation.title = t('operations.delete.title');
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
function Disconnect(selectedIDs, context) {
|
||||
var vertices = _.filter(selectedIDs, function vertex(entityId) {
|
||||
return context.geometry(entityId) === 'vertex';
|
||||
});
|
||||
|
||||
var entityId = vertices[0],
|
||||
action = iD.actions.Disconnect(entityId);
|
||||
|
||||
if (selectedIDs.length > 1) {
|
||||
action.limitWays(_.without(selectedIDs, entityId));
|
||||
}
|
||||
|
||||
var operation = function() {
|
||||
context.perform(action, t('operations.disconnect.annotation'));
|
||||
};
|
||||
|
||||
operation.available = function() {
|
||||
return vertices.length === 1;
|
||||
};
|
||||
|
||||
operation.disabled = function() {
|
||||
var reason;
|
||||
if (_.some(selectedIDs, context.hasHiddenConnections)) {
|
||||
reason = 'connected_to_hidden';
|
||||
}
|
||||
return action.disabled(context.graph()) || reason;
|
||||
};
|
||||
|
||||
operation.tooltip = function() {
|
||||
var disable = operation.disabled();
|
||||
return disable ?
|
||||
t('operations.disconnect.' + disable) :
|
||||
t('operations.disconnect.description');
|
||||
};
|
||||
|
||||
operation.id = 'disconnect';
|
||||
operation.keys = [t('operations.disconnect.key')];
|
||||
operation.title = t('operations.disconnect.title');
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
function Merge(selectedIDs, context) {
|
||||
var join = iD.actions.Join(selectedIDs),
|
||||
merge = iD.actions.Merge(selectedIDs),
|
||||
mergePolygon = iD.actions.MergePolygon(selectedIDs);
|
||||
|
||||
var operation = function() {
|
||||
var annotation = t('operations.merge.annotation', {n: selectedIDs.length}),
|
||||
action;
|
||||
|
||||
if (!join.disabled(context.graph())) {
|
||||
action = join;
|
||||
} else if (!merge.disabled(context.graph())) {
|
||||
action = merge;
|
||||
} else {
|
||||
action = mergePolygon;
|
||||
}
|
||||
|
||||
context.perform(action, annotation);
|
||||
context.enter(iD.modes.Select(context, selectedIDs.filter(function(id) { return context.hasEntity(id); }))
|
||||
.suppressMenu(true));
|
||||
};
|
||||
|
||||
operation.available = function() {
|
||||
return selectedIDs.length >= 2;
|
||||
};
|
||||
|
||||
operation.disabled = function() {
|
||||
return join.disabled(context.graph()) &&
|
||||
merge.disabled(context.graph()) &&
|
||||
mergePolygon.disabled(context.graph());
|
||||
};
|
||||
|
||||
operation.tooltip = function() {
|
||||
var j = join.disabled(context.graph()),
|
||||
m = merge.disabled(context.graph()),
|
||||
p = mergePolygon.disabled(context.graph());
|
||||
|
||||
if (j === 'restriction' && m && p)
|
||||
return t('operations.merge.restriction', {relation: context.presets().item('type/restriction').name()});
|
||||
|
||||
if (p === 'incomplete_relation' && j && m)
|
||||
return t('operations.merge.incomplete_relation');
|
||||
|
||||
if (j && m && p)
|
||||
return t('operations.merge.' + j);
|
||||
|
||||
return t('operations.merge.description');
|
||||
};
|
||||
|
||||
operation.id = 'merge';
|
||||
operation.keys = [t('operations.merge.key')];
|
||||
operation.title = t('operations.merge.title');
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
function Move(selectedIDs, context) {
|
||||
var extent = selectedIDs.reduce(function(extent, id) {
|
||||
return extent.extend(context.entity(id).extent(context.graph()));
|
||||
}, iD.geo.Extent());
|
||||
|
||||
var operation = function() {
|
||||
context.enter(iD.modes.Move(context, selectedIDs));
|
||||
};
|
||||
|
||||
operation.available = function() {
|
||||
return selectedIDs.length > 1 ||
|
||||
context.entity(selectedIDs[0]).type !== 'node';
|
||||
};
|
||||
|
||||
operation.disabled = function() {
|
||||
var reason;
|
||||
if (extent.area() && extent.percentContainedIn(context.extent()) < 0.8) {
|
||||
reason = 'too_large';
|
||||
} else if (_.some(selectedIDs, context.hasHiddenConnections)) {
|
||||
reason = 'connected_to_hidden';
|
||||
}
|
||||
return iD.actions.Move(selectedIDs).disabled(context.graph()) || reason;
|
||||
};
|
||||
|
||||
operation.tooltip = function() {
|
||||
var disable = operation.disabled();
|
||||
return disable ?
|
||||
t('operations.move.' + disable) :
|
||||
t('operations.move.description');
|
||||
};
|
||||
|
||||
operation.id = 'move';
|
||||
operation.keys = [t('operations.move.key')];
|
||||
operation.title = t('operations.move.title');
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
function Orthogonalize(selectedIDs, context) {
|
||||
var entityId = selectedIDs[0],
|
||||
entity = context.entity(entityId),
|
||||
extent = entity.extent(context.graph()),
|
||||
geometry = context.geometry(entityId),
|
||||
action = iD.actions.Orthogonalize(entityId, context.projection);
|
||||
|
||||
var operation = function() {
|
||||
var annotation = t('operations.orthogonalize.annotation.' + geometry);
|
||||
context.perform(action, annotation);
|
||||
};
|
||||
|
||||
operation.available = function() {
|
||||
return selectedIDs.length === 1 &&
|
||||
entity.type === 'way' &&
|
||||
entity.isClosed() &&
|
||||
_.uniq(entity.nodes).length > 2;
|
||||
};
|
||||
|
||||
operation.disabled = function() {
|
||||
var reason;
|
||||
if (extent.percentContainedIn(context.extent()) < 0.8) {
|
||||
reason = 'too_large';
|
||||
} else if (context.hasHiddenConnections(entityId)) {
|
||||
reason = 'connected_to_hidden';
|
||||
}
|
||||
return action.disabled(context.graph()) || reason;
|
||||
};
|
||||
|
||||
operation.tooltip = function() {
|
||||
var disable = operation.disabled();
|
||||
return disable ?
|
||||
t('operations.orthogonalize.' + disable) :
|
||||
t('operations.orthogonalize.description.' + geometry);
|
||||
};
|
||||
|
||||
operation.id = 'orthogonalize';
|
||||
operation.keys = [t('operations.orthogonalize.key')];
|
||||
operation.title = t('operations.orthogonalize.title');
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
function Reverse(selectedIDs, context) {
|
||||
var entityId = selectedIDs[0];
|
||||
|
||||
var operation = function() {
|
||||
context.perform(
|
||||
iD.actions.Reverse(entityId),
|
||||
t('operations.reverse.annotation'));
|
||||
};
|
||||
|
||||
operation.available = function() {
|
||||
return selectedIDs.length === 1 &&
|
||||
context.geometry(entityId) === 'line';
|
||||
};
|
||||
|
||||
operation.disabled = function() {
|
||||
return false;
|
||||
};
|
||||
|
||||
operation.tooltip = function() {
|
||||
return t('operations.reverse.description');
|
||||
};
|
||||
|
||||
operation.id = 'reverse';
|
||||
operation.keys = [t('operations.reverse.key')];
|
||||
operation.title = t('operations.reverse.title');
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
function Rotate(selectedIDs, context) {
|
||||
var entityId = selectedIDs[0],
|
||||
entity = context.entity(entityId),
|
||||
extent = entity.extent(context.graph()),
|
||||
geometry = context.geometry(entityId);
|
||||
|
||||
var operation = function() {
|
||||
context.enter(iD.modes.RotateWay(context, entityId));
|
||||
};
|
||||
|
||||
operation.available = function() {
|
||||
if (selectedIDs.length !== 1 || entity.type !== 'way')
|
||||
return false;
|
||||
if (geometry === 'area')
|
||||
return true;
|
||||
if (entity.isClosed() &&
|
||||
context.graph().parentRelations(entity).some(function(r) { return r.isMultipolygon(); }))
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
operation.disabled = function() {
|
||||
if (extent.percentContainedIn(context.extent()) < 0.8) {
|
||||
return 'too_large';
|
||||
} else if (context.hasHiddenConnections(entityId)) {
|
||||
return 'connected_to_hidden';
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
operation.tooltip = function() {
|
||||
var disable = operation.disabled();
|
||||
return disable ?
|
||||
t('operations.rotate.' + disable) :
|
||||
t('operations.rotate.description');
|
||||
};
|
||||
|
||||
operation.id = 'rotate';
|
||||
operation.keys = [t('operations.rotate.key')];
|
||||
operation.title = t('operations.rotate.title');
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
function Split(selectedIDs, context) {
|
||||
var vertices = _.filter(selectedIDs, function vertex(entityId) {
|
||||
return context.geometry(entityId) === 'vertex';
|
||||
});
|
||||
|
||||
var entityId = vertices[0],
|
||||
action = iD.actions.Split(entityId);
|
||||
|
||||
if (selectedIDs.length > 1) {
|
||||
action.limitWays(_.without(selectedIDs, entityId));
|
||||
}
|
||||
|
||||
var operation = function() {
|
||||
var annotation;
|
||||
|
||||
var ways = action.ways(context.graph());
|
||||
if (ways.length === 1) {
|
||||
annotation = t('operations.split.annotation.' + context.geometry(ways[0].id));
|
||||
} else {
|
||||
annotation = t('operations.split.annotation.multiple', {n: ways.length});
|
||||
}
|
||||
|
||||
var difference = context.perform(action, annotation);
|
||||
context.enter(iD.modes.Select(context, difference.extantIDs()));
|
||||
};
|
||||
|
||||
operation.available = function() {
|
||||
return vertices.length === 1;
|
||||
};
|
||||
|
||||
operation.disabled = function() {
|
||||
var reason;
|
||||
if (_.some(selectedIDs, context.hasHiddenConnections)) {
|
||||
reason = 'connected_to_hidden';
|
||||
}
|
||||
return action.disabled(context.graph()) || reason;
|
||||
};
|
||||
|
||||
operation.tooltip = function() {
|
||||
var disable = operation.disabled();
|
||||
if (disable) {
|
||||
return t('operations.split.' + disable);
|
||||
}
|
||||
|
||||
var ways = action.ways(context.graph());
|
||||
if (ways.length === 1) {
|
||||
return t('operations.split.description.' + context.geometry(ways[0].id));
|
||||
} else {
|
||||
return t('operations.split.description.multiple');
|
||||
}
|
||||
};
|
||||
|
||||
operation.id = 'split';
|
||||
operation.keys = [t('operations.split.key')];
|
||||
operation.title = t('operations.split.title');
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
function Straighten(selectedIDs, context) {
|
||||
var entityId = selectedIDs[0],
|
||||
action = iD.actions.Straighten(entityId, context.projection);
|
||||
|
||||
function operation() {
|
||||
var annotation = t('operations.straighten.annotation');
|
||||
context.perform(action, annotation);
|
||||
}
|
||||
|
||||
operation.available = function() {
|
||||
var entity = context.entity(entityId);
|
||||
return selectedIDs.length === 1 &&
|
||||
entity.type === 'way' &&
|
||||
!entity.isClosed() &&
|
||||
_.uniq(entity.nodes).length > 2;
|
||||
};
|
||||
|
||||
operation.disabled = function() {
|
||||
var reason;
|
||||
if (context.hasHiddenConnections(entityId)) {
|
||||
reason = 'connected_to_hidden';
|
||||
}
|
||||
return action.disabled(context.graph()) || reason;
|
||||
};
|
||||
|
||||
operation.tooltip = function() {
|
||||
var disable = operation.disabled();
|
||||
return disable ?
|
||||
t('operations.straighten.' + disable) :
|
||||
t('operations.straighten.description');
|
||||
};
|
||||
|
||||
operation.id = 'straighten';
|
||||
operation.keys = [t('operations.straighten.key')];
|
||||
operation.title = t('operations.straighten.title');
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
exports.Circularize = Circularize;
|
||||
exports.Continue = Continue;
|
||||
exports.Delete = Delete;
|
||||
exports.Disconnect = Disconnect;
|
||||
exports.Merge = Merge;
|
||||
exports.Move = Move;
|
||||
exports.Orthogonalize = Orthogonalize;
|
||||
exports.Reverse = Reverse;
|
||||
exports.Rotate = Rotate;
|
||||
exports.Split = Split;
|
||||
exports.Straighten = Straighten;
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
}));
|
||||
@@ -1,481 +0,0 @@
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
||||
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
||||
(factory((global.iD = global.iD || {}, global.iD.presets = global.iD.presets || {})));
|
||||
}(this, function (exports) { 'use strict';
|
||||
|
||||
function Collection(collection) {
|
||||
var maxSearchResults = 50,
|
||||
maxSuggestionResults = 10;
|
||||
|
||||
var presets = {
|
||||
|
||||
collection: collection,
|
||||
|
||||
item: function(id) {
|
||||
return _.find(collection, function(d) {
|
||||
return d.id === id;
|
||||
});
|
||||
},
|
||||
|
||||
matchGeometry: function(geometry) {
|
||||
return Collection(collection.filter(function(d) {
|
||||
return d.matchGeometry(geometry);
|
||||
}));
|
||||
},
|
||||
|
||||
search: function(value, geometry) {
|
||||
if (!value) return this;
|
||||
|
||||
value = value.toLowerCase();
|
||||
|
||||
var searchable = _.filter(collection, function(a) {
|
||||
return a.searchable !== false && a.suggestion !== true;
|
||||
}),
|
||||
suggestions = _.filter(collection, function(a) {
|
||||
return a.suggestion === true;
|
||||
});
|
||||
|
||||
function leading(a) {
|
||||
var index = a.indexOf(value);
|
||||
return index === 0 || a[index - 1] === ' ';
|
||||
}
|
||||
|
||||
// matches value to preset.name
|
||||
var leading_name = _.filter(searchable, function(a) {
|
||||
return leading(a.name().toLowerCase());
|
||||
}).sort(function(a, b) {
|
||||
var i = a.name().toLowerCase().indexOf(value) - b.name().toLowerCase().indexOf(value);
|
||||
if (i === 0) return a.name().length - b.name().length;
|
||||
else return i;
|
||||
});
|
||||
|
||||
// matches value to preset.terms values
|
||||
var leading_terms = _.filter(searchable, function(a) {
|
||||
return _.some(a.terms() || [], leading);
|
||||
});
|
||||
|
||||
// matches value to preset.tags values
|
||||
var leading_tag_values = _.filter(searchable, function(a) {
|
||||
return _.some(_.without(_.values(a.tags || {}), '*'), leading);
|
||||
});
|
||||
|
||||
|
||||
// finds close matches to value in preset.name
|
||||
var levenstein_name = searchable.map(function(a) {
|
||||
return {
|
||||
preset: a,
|
||||
dist: iD.util.editDistance(value, a.name().toLowerCase())
|
||||
};
|
||||
}).filter(function(a) {
|
||||
return a.dist + Math.min(value.length - a.preset.name().length, 0) < 3;
|
||||
}).sort(function(a, b) {
|
||||
return a.dist - b.dist;
|
||||
}).map(function(a) {
|
||||
return a.preset;
|
||||
});
|
||||
|
||||
// finds close matches to value in preset.terms
|
||||
var leventstein_terms = _.filter(searchable, function(a) {
|
||||
return _.some(a.terms() || [], function(b) {
|
||||
return iD.util.editDistance(value, b) + Math.min(value.length - b.length, 0) < 3;
|
||||
});
|
||||
});
|
||||
|
||||
function suggestionName(name) {
|
||||
var nameArray = name.split(' - ');
|
||||
if (nameArray.length > 1) {
|
||||
name = nameArray.slice(0, nameArray.length-1).join(' - ');
|
||||
}
|
||||
return name.toLowerCase();
|
||||
}
|
||||
|
||||
var leading_suggestions = _.filter(suggestions, function(a) {
|
||||
return leading(suggestionName(a.name()));
|
||||
}).sort(function(a, b) {
|
||||
a = suggestionName(a.name());
|
||||
b = suggestionName(b.name());
|
||||
var i = a.indexOf(value) - b.indexOf(value);
|
||||
if (i === 0) return a.length - b.length;
|
||||
else return i;
|
||||
});
|
||||
|
||||
var leven_suggestions = suggestions.map(function(a) {
|
||||
return {
|
||||
preset: a,
|
||||
dist: iD.util.editDistance(value, suggestionName(a.name()))
|
||||
};
|
||||
}).filter(function(a) {
|
||||
return a.dist + Math.min(value.length - suggestionName(a.preset.name()).length, 0) < 1;
|
||||
}).sort(function(a, b) {
|
||||
return a.dist - b.dist;
|
||||
}).map(function(a) {
|
||||
return a.preset;
|
||||
});
|
||||
|
||||
var other = presets.item(geometry);
|
||||
|
||||
var results = leading_name.concat(
|
||||
leading_terms,
|
||||
leading_tag_values,
|
||||
leading_suggestions.slice(0, maxSuggestionResults+5),
|
||||
levenstein_name,
|
||||
leventstein_terms,
|
||||
leven_suggestions.slice(0, maxSuggestionResults)
|
||||
).slice(0, maxSearchResults-1);
|
||||
|
||||
return Collection(_.uniq(
|
||||
results.concat(other)
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
return presets;
|
||||
}
|
||||
|
||||
function Category(id, category, all) {
|
||||
category = _.clone(category);
|
||||
|
||||
category.id = id;
|
||||
|
||||
category.members = Collection(category.members.map(function(id) {
|
||||
return all.item(id);
|
||||
}));
|
||||
|
||||
category.matchGeometry = function(geometry) {
|
||||
return category.geometry.indexOf(geometry) >= 0;
|
||||
};
|
||||
|
||||
category.matchScore = function() { return -1; };
|
||||
|
||||
category.name = function() {
|
||||
return t('presets.categories.' + id + '.name', {'default': id});
|
||||
};
|
||||
|
||||
category.terms = function() {
|
||||
return [];
|
||||
};
|
||||
|
||||
return category;
|
||||
}
|
||||
|
||||
function Field(id, field) {
|
||||
field = _.clone(field);
|
||||
|
||||
field.id = id;
|
||||
|
||||
field.matchGeometry = function(geometry) {
|
||||
return !field.geometry || field.geometry === geometry;
|
||||
};
|
||||
|
||||
field.t = function(scope, options) {
|
||||
return t('presets.fields.' + id + '.' + scope, options);
|
||||
};
|
||||
|
||||
field.label = function() {
|
||||
return field.t('label', {'default': id});
|
||||
};
|
||||
|
||||
var placeholder = field.placeholder;
|
||||
field.placeholder = function() {
|
||||
return field.t('placeholder', {'default': placeholder});
|
||||
};
|
||||
|
||||
return field;
|
||||
}
|
||||
|
||||
function Preset(id, preset, fields) {
|
||||
preset = _.clone(preset);
|
||||
|
||||
preset.id = id;
|
||||
preset.fields = (preset.fields || []).map(getFields);
|
||||
preset.geometry = (preset.geometry || []);
|
||||
|
||||
function getFields(f) {
|
||||
return fields[f];
|
||||
}
|
||||
|
||||
preset.matchGeometry = function(geometry) {
|
||||
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]) {
|
||||
score += matchScore;
|
||||
} else if (tags[t] === '*' && t in entity.tags) {
|
||||
score += matchScore / 2;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return score;
|
||||
};
|
||||
|
||||
preset.t = function(scope, options) {
|
||||
return t('presets.presets.' + id + '.' + scope, options);
|
||||
};
|
||||
|
||||
var name = preset.name;
|
||||
preset.name = function() {
|
||||
if (preset.suggestion) {
|
||||
id = id.split('/');
|
||||
id = id[0] + '/' + id[1];
|
||||
return name + ' - ' + t('presets.presets.' + id + '.name');
|
||||
}
|
||||
return preset.t('name', {'default': name});
|
||||
};
|
||||
|
||||
preset.terms = function() {
|
||||
return preset.t('terms', {'default': ''}).toLowerCase().trim().split(/\s*,+\s*/);
|
||||
};
|
||||
|
||||
preset.isFallback = function() {
|
||||
var tagCount = Object.keys(preset.tags).length;
|
||||
return tagCount === 0 || (tagCount === 1 && preset.tags.hasOwnProperty('area'));
|
||||
};
|
||||
|
||||
preset.reference = function(geometry) {
|
||||
var key = Object.keys(preset.tags)[0],
|
||||
value = preset.tags[key];
|
||||
|
||||
if (geometry === 'relation' && key === 'type') {
|
||||
return { rtype: value };
|
||||
} else if (value === '*') {
|
||||
return { key: key };
|
||||
} else {
|
||||
return { key: key, value: value };
|
||||
}
|
||||
};
|
||||
|
||||
var removeTags = preset.removeTags || preset.tags;
|
||||
preset.removeTags = function(tags, geometry) {
|
||||
tags = _.omit(tags, _.keys(removeTags));
|
||||
|
||||
for (var f in preset.fields) {
|
||||
var field = preset.fields[f];
|
||||
if (field.matchGeometry(geometry) && field.default === tags[field.key]) {
|
||||
delete tags[field.key];
|
||||
}
|
||||
}
|
||||
|
||||
delete tags.area;
|
||||
return tags;
|
||||
};
|
||||
|
||||
var applyTags = preset.addTags || preset.tags;
|
||||
preset.applyTags = function(tags, geometry) {
|
||||
var k;
|
||||
|
||||
tags = _.clone(tags);
|
||||
|
||||
for (k in applyTags) {
|
||||
if (applyTags[k] === '*') {
|
||||
tags[k] = 'yes';
|
||||
} else {
|
||||
tags[k] = applyTags[k];
|
||||
}
|
||||
}
|
||||
|
||||
// Add area=yes if necessary.
|
||||
// This is necessary if the geometry is already an area (e.g. user drew an area) AND any of:
|
||||
// 1. chosen preset could be either an area or a line (`barrier=city_wall`)
|
||||
// 2. chosen preset doesn't have a key in areaKeys (`railway=station`)
|
||||
if (geometry === 'area') {
|
||||
var needsAreaTag = true;
|
||||
if (preset.geometry.indexOf('line') === -1) {
|
||||
for (k in applyTags) {
|
||||
if (k in iD.areaKeys) {
|
||||
needsAreaTag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (needsAreaTag) {
|
||||
tags.area = 'yes';
|
||||
}
|
||||
}
|
||||
|
||||
for (var f in preset.fields) {
|
||||
var field = preset.fields[f];
|
||||
if (field.matchGeometry(geometry) && field.key && !tags[field.key] && field.default) {
|
||||
tags[field.key] = field.default;
|
||||
}
|
||||
}
|
||||
|
||||
return tags;
|
||||
};
|
||||
|
||||
return preset;
|
||||
}
|
||||
|
||||
function presets() {
|
||||
// an iD.presets.Collection with methods for
|
||||
// loading new data and returning defaults
|
||||
|
||||
var all = Collection([]),
|
||||
defaults = { area: all, line: all, point: all, vertex: all, relation: all },
|
||||
fields = {},
|
||||
universal = [],
|
||||
recent = Collection([]);
|
||||
|
||||
// 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;
|
||||
|
||||
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.item(geometry);
|
||||
};
|
||||
|
||||
// Because of the open nature of tagging, iD will never have a complete
|
||||
// list of tags used in OSM, so we want it to have logic like "assume
|
||||
// that a closed way with an amenity tag is an area, unless the amenity
|
||||
// is one of these specific types". This function computes a structure
|
||||
// that allows testing of such conditions, based on the presets designated
|
||||
// as as supporting (or not supporting) the area geometry.
|
||||
//
|
||||
// The returned object L is a whitelist/blacklist of tags. A closed way
|
||||
// with a tag (k, v) is considered to be an area if `k in L && !(v in L[k])`
|
||||
// (see `iD.Way#isArea()`). In other words, the keys of L form the whitelist,
|
||||
// and the subkeys form the blacklist.
|
||||
all.areaKeys = function() {
|
||||
var areaKeys = {},
|
||||
ignore = ['barrier', 'highway', 'footway', 'railway', 'type'],
|
||||
presets = _.reject(all.collection, 'suggestion');
|
||||
|
||||
// whitelist
|
||||
presets.forEach(function(d) {
|
||||
for (var key in d.tags) break;
|
||||
if (!key) return;
|
||||
if (ignore.indexOf(key) !== -1) return;
|
||||
|
||||
if (d.geometry.indexOf('area') !== -1) {
|
||||
areaKeys[key] = areaKeys[key] || {};
|
||||
}
|
||||
});
|
||||
|
||||
// blacklist
|
||||
presets.forEach(function(d) {
|
||||
for (var key in d.tags) break;
|
||||
if (!key) return;
|
||||
if (ignore.indexOf(key) !== -1) return;
|
||||
|
||||
var value = d.tags[key];
|
||||
if (d.geometry.indexOf('area') === -1 &&
|
||||
d.geometry.indexOf('line') !== -1 &&
|
||||
key in areaKeys && value !== '*') {
|
||||
areaKeys[key][value] = true;
|
||||
}
|
||||
});
|
||||
|
||||
return areaKeys;
|
||||
};
|
||||
|
||||
all.load = function(d) {
|
||||
|
||||
if (d.fields) {
|
||||
_.forEach(d.fields, function(d, id) {
|
||||
fields[id] = Field(id, d);
|
||||
if (d.universal) universal.push(fields[id]);
|
||||
});
|
||||
}
|
||||
|
||||
if (d.presets) {
|
||||
_.forEach(d.presets, function(d, id) {
|
||||
all.collection.push(Preset(id, d, fields));
|
||||
});
|
||||
}
|
||||
|
||||
if (d.categories) {
|
||||
_.forEach(d.categories, function(d, id) {
|
||||
all.collection.push(Category(id, d, all));
|
||||
});
|
||||
}
|
||||
|
||||
if (d.defaults) {
|
||||
var getItem = _.bind(all.item, all);
|
||||
defaults = {
|
||||
area: Collection(d.defaults.area.map(getItem)),
|
||||
line: Collection(d.defaults.line.map(getItem)),
|
||||
point: Collection(d.defaults.point.map(getItem)),
|
||||
vertex: Collection(d.defaults.vertex.map(getItem)),
|
||||
relation: Collection(d.defaults.relation.map(getItem))
|
||||
};
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
all.field = function(id) {
|
||||
return fields[id];
|
||||
};
|
||||
|
||||
all.universal = function() {
|
||||
return universal;
|
||||
};
|
||||
|
||||
all.defaults = function(geometry, n) {
|
||||
var rec = recent.matchGeometry(geometry).collection.slice(0, 4),
|
||||
def = _.uniq(rec.concat(defaults[geometry].collection)).slice(0, n - 1);
|
||||
return Collection(_.uniq(rec.concat(def).concat(all.item(geometry))));
|
||||
};
|
||||
|
||||
all.choose = function(preset) {
|
||||
if (!preset.isFallback()) {
|
||||
recent = Collection(_.uniq([preset].concat(recent.collection)));
|
||||
}
|
||||
return all;
|
||||
};
|
||||
|
||||
return all;
|
||||
}
|
||||
|
||||
exports.Category = Category;
|
||||
exports.Collection = Collection;
|
||||
exports.Field = Field;
|
||||
exports.Preset = Preset;
|
||||
exports.presets = presets;
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
}));
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,272 +0,0 @@
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
||||
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
||||
(factory((global.iD = global.iD || {}, global.iD.util = global.iD.util || {})));
|
||||
}(this, function (exports) { 'use strict';
|
||||
|
||||
function tagText(entity) {
|
||||
return d3.entries(entity.tags).map(function(e) {
|
||||
return e.key + '=' + e.value;
|
||||
}).join(', ');
|
||||
}
|
||||
|
||||
function entitySelector(ids) {
|
||||
return ids.length ? '.' + ids.join(',.') : 'nothing';
|
||||
}
|
||||
|
||||
function entityOrMemberSelector(ids, graph) {
|
||||
var s = entitySelector(ids);
|
||||
|
||||
ids.forEach(function(id) {
|
||||
var entity = graph.hasEntity(id);
|
||||
if (entity && entity.type === 'relation') {
|
||||
entity.members.forEach(function(member) {
|
||||
s += ',.' + member.id;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
function displayName(entity) {
|
||||
var localeName = 'name:' + iD.detect().locale.toLowerCase().split('-')[0];
|
||||
return entity.tags[localeName] || entity.tags.name || entity.tags.ref;
|
||||
}
|
||||
|
||||
function displayType(id) {
|
||||
return {
|
||||
n: t('inspector.node'),
|
||||
w: t('inspector.way'),
|
||||
r: t('inspector.relation')
|
||||
}[id.charAt(0)];
|
||||
}
|
||||
|
||||
function stringQs(str) {
|
||||
return str.split('&').reduce(function(obj, pair){
|
||||
var parts = pair.split('=');
|
||||
if (parts.length === 2) {
|
||||
obj[parts[0]] = (null === parts[1]) ? '' : decodeURIComponent(parts[1]);
|
||||
}
|
||||
return obj;
|
||||
}, {});
|
||||
}
|
||||
|
||||
function qsString(obj, noencode) {
|
||||
function softEncode(s) {
|
||||
// encode everything except special characters used in certain hash parameters:
|
||||
// "/" in map states, ":", ",", {" and "}" in background
|
||||
return encodeURIComponent(s).replace(/(%2F|%3A|%2C|%7B|%7D)/g, decodeURIComponent);
|
||||
}
|
||||
return Object.keys(obj).sort().map(function(key) {
|
||||
return encodeURIComponent(key) + '=' + (
|
||||
noencode ? softEncode(obj[key]) : encodeURIComponent(obj[key]));
|
||||
}).join('&');
|
||||
}
|
||||
|
||||
function prefixDOMProperty(property) {
|
||||
var prefixes = ['webkit', 'ms', 'moz', 'o'],
|
||||
i = -1,
|
||||
n = prefixes.length,
|
||||
s = document.body;
|
||||
|
||||
if (property in s)
|
||||
return property;
|
||||
|
||||
property = property.substr(0, 1).toUpperCase() + property.substr(1);
|
||||
|
||||
while (++i < n)
|
||||
if (prefixes[i] + property in s)
|
||||
return prefixes[i] + property;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function prefixCSSProperty(property) {
|
||||
var prefixes = ['webkit', 'ms', 'Moz', 'O'],
|
||||
i = -1,
|
||||
n = prefixes.length,
|
||||
s = document.body.style;
|
||||
|
||||
if (property.toLowerCase() in s)
|
||||
return property.toLowerCase();
|
||||
|
||||
while (++i < n)
|
||||
if (prefixes[i] + property in s)
|
||||
return '-' + prefixes[i].toLowerCase() + property.replace(/([A-Z])/g, '-$1').toLowerCase();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
var transformProperty;
|
||||
function setTransform(el, x, y, scale) {
|
||||
var prop = transformProperty = transformProperty || prefixCSSProperty('Transform'),
|
||||
translate = iD.detect().opera ?
|
||||
'translate(' + x + 'px,' + y + 'px)' :
|
||||
'translate3d(' + x + 'px,' + y + 'px,0)';
|
||||
return el.style(prop, translate + (scale ? ' scale(' + scale + ')' : ''));
|
||||
}
|
||||
|
||||
function getStyle(selector) {
|
||||
for (var i = 0; i < document.styleSheets.length; i++) {
|
||||
var rules = document.styleSheets[i].rules || document.styleSheets[i].cssRules || [];
|
||||
for (var k = 0; k < rules.length; k++) {
|
||||
var selectorText = rules[k].selectorText && rules[k].selectorText.split(', ');
|
||||
if (_.includes(selectorText, selector)) {
|
||||
return rules[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function editDistance(a, b) {
|
||||
if (a.length === 0) return b.length;
|
||||
if (b.length === 0) return a.length;
|
||||
var matrix = [];
|
||||
for (var i = 0; i <= b.length; i++) { matrix[i] = [i]; }
|
||||
for (var j = 0; j <= a.length; j++) { matrix[0][j] = j; }
|
||||
for (i = 1; i <= b.length; i++) {
|
||||
for (j = 1; j <= a.length; j++) {
|
||||
if (b.charAt(i-1) === a.charAt(j-1)) {
|
||||
matrix[i][j] = matrix[i-1][j-1];
|
||||
} else {
|
||||
matrix[i][j] = Math.min(matrix[i-1][j-1] + 1, // substitution
|
||||
Math.min(matrix[i][j-1] + 1, // insertion
|
||||
matrix[i-1][j] + 1)); // deletion
|
||||
}
|
||||
}
|
||||
}
|
||||
return matrix[b.length][a.length];
|
||||
}
|
||||
|
||||
// a d3.mouse-alike which
|
||||
// 1. Only works on HTML elements, not SVG
|
||||
// 2. Does not cause style recalculation
|
||||
function fastMouse(container) {
|
||||
var rect = container.getBoundingClientRect(),
|
||||
rectLeft = rect.left,
|
||||
rectTop = rect.top,
|
||||
clientLeft = +container.clientLeft,
|
||||
clientTop = +container.clientTop;
|
||||
return function(e) {
|
||||
return [
|
||||
e.clientX - rectLeft - clientLeft,
|
||||
e.clientY - rectTop - clientTop];
|
||||
};
|
||||
}
|
||||
|
||||
/* eslint-disable no-proto */
|
||||
var getPrototypeOf = Object.getPrototypeOf || function(obj) { return obj.__proto__; };
|
||||
/* eslint-enable no-proto */
|
||||
|
||||
function asyncMap(inputs, func, callback) {
|
||||
var remaining = inputs.length,
|
||||
results = [],
|
||||
errors = [];
|
||||
|
||||
inputs.forEach(function(d, i) {
|
||||
func(d, function done(err, data) {
|
||||
errors[i] = err;
|
||||
results[i] = data;
|
||||
remaining--;
|
||||
if (!remaining) callback(errors, results);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// wraps an index to an interval [0..length-1]
|
||||
function wrap(index, length) {
|
||||
if (index < 0)
|
||||
index += Math.ceil(-index/length)*length;
|
||||
return index % length;
|
||||
}
|
||||
|
||||
// A per-domain session mutex backed by a cookie and dead man's
|
||||
// switch. If the session crashes, the mutex will auto-release
|
||||
// after 5 seconds.
|
||||
|
||||
function SessionMutex(name) {
|
||||
var mutex = {},
|
||||
intervalID;
|
||||
|
||||
function renew() {
|
||||
var expires = new Date();
|
||||
expires.setSeconds(expires.getSeconds() + 5);
|
||||
document.cookie = name + '=1; expires=' + expires.toUTCString();
|
||||
}
|
||||
|
||||
mutex.lock = function() {
|
||||
if (intervalID) return true;
|
||||
var cookie = document.cookie.replace(new RegExp('(?:(?:^|.*;)\\s*' + name + '\\s*\\=\\s*([^;]*).*$)|^.*$'), '$1');
|
||||
if (cookie) return false;
|
||||
renew();
|
||||
intervalID = window.setInterval(renew, 4000);
|
||||
return true;
|
||||
};
|
||||
|
||||
mutex.unlock = function() {
|
||||
if (!intervalID) return;
|
||||
document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT';
|
||||
clearInterval(intervalID);
|
||||
intervalID = null;
|
||||
};
|
||||
|
||||
mutex.locked = function() {
|
||||
return !!intervalID;
|
||||
};
|
||||
|
||||
return mutex;
|
||||
}
|
||||
|
||||
function SuggestNames(preset, suggestions) {
|
||||
preset = preset.id.split('/', 2);
|
||||
var k = preset[0],
|
||||
v = preset[1];
|
||||
|
||||
return function(value, callback) {
|
||||
var result = [];
|
||||
if (value && value.length > 2) {
|
||||
if (suggestions[k] && suggestions[k][v]) {
|
||||
for (var sugg in suggestions[k][v]) {
|
||||
var dist = iD.util.editDistance(value, sugg.substring(0, value.length));
|
||||
if (dist < 3) {
|
||||
result.push({
|
||||
title: sugg,
|
||||
value: sugg,
|
||||
dist: dist
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
result.sort(function(a, b) {
|
||||
return a.dist - b.dist;
|
||||
});
|
||||
}
|
||||
result = result.slice(0,3);
|
||||
callback(result);
|
||||
};
|
||||
}
|
||||
|
||||
exports.tagText = tagText;
|
||||
exports.entitySelector = entitySelector;
|
||||
exports.entityOrMemberSelector = entityOrMemberSelector;
|
||||
exports.displayName = displayName;
|
||||
exports.displayType = displayType;
|
||||
exports.stringQs = stringQs;
|
||||
exports.qsString = qsString;
|
||||
exports.prefixDOMProperty = prefixDOMProperty;
|
||||
exports.prefixCSSProperty = prefixCSSProperty;
|
||||
exports.setTransform = setTransform;
|
||||
exports.getStyle = getStyle;
|
||||
exports.editDistance = editDistance;
|
||||
exports.fastMouse = fastMouse;
|
||||
exports.getPrototypeOf = getPrototypeOf;
|
||||
exports.asyncMap = asyncMap;
|
||||
exports.wrap = wrap;
|
||||
exports.SessionMutex = SessionMutex;
|
||||
exports.SuggestNames = SuggestNames;
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
}));
|
||||
@@ -1,121 +0,0 @@
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
||||
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
||||
(factory((global.iD = global.iD || {}, global.iD.validations = global.iD.validations || {})));
|
||||
}(this, function (exports) { 'use strict';
|
||||
|
||||
function DeprecatedTag() {
|
||||
|
||||
var validation = function(changes) {
|
||||
var warnings = [];
|
||||
for (var i = 0; i < changes.created.length; i++) {
|
||||
var change = changes.created[i],
|
||||
deprecatedTags = change.deprecatedTags();
|
||||
|
||||
if (!_.isEmpty(deprecatedTags)) {
|
||||
var tags = iD.util.tagText({ tags: deprecatedTags });
|
||||
warnings.push({
|
||||
id: 'deprecated_tags',
|
||||
message: t('validations.deprecated_tags', { tags: tags }),
|
||||
entity: change
|
||||
});
|
||||
}
|
||||
}
|
||||
return warnings;
|
||||
};
|
||||
|
||||
return validation;
|
||||
}
|
||||
|
||||
function ManyDeletions() {
|
||||
var threshold = 100;
|
||||
|
||||
var validation = function(changes) {
|
||||
var warnings = [];
|
||||
if (changes.deleted.length > threshold) {
|
||||
warnings.push({
|
||||
id: 'many_deletions',
|
||||
message: t('validations.many_deletions', { n: changes.deleted.length })
|
||||
});
|
||||
}
|
||||
return warnings;
|
||||
};
|
||||
|
||||
return validation;
|
||||
}
|
||||
|
||||
function MissingTag() {
|
||||
|
||||
// Slightly stricter check than Entity#isUsed (#3091)
|
||||
function hasTags(entity, graph) {
|
||||
return _.without(Object.keys(entity.tags), 'area', 'name').length > 0 ||
|
||||
graph.parentRelations(entity).length > 0;
|
||||
}
|
||||
|
||||
var validation = function(changes, graph) {
|
||||
var warnings = [];
|
||||
for (var i = 0; i < changes.created.length; i++) {
|
||||
var change = changes.created[i],
|
||||
geometry = change.geometry(graph);
|
||||
|
||||
if ((geometry === 'point' || geometry === 'line' || geometry === 'area') && !hasTags(change, graph)) {
|
||||
warnings.push({
|
||||
id: 'missing_tag',
|
||||
message: t('validations.untagged_' + geometry),
|
||||
tooltip: t('validations.untagged_' + geometry + '_tooltip'),
|
||||
entity: change
|
||||
});
|
||||
}
|
||||
}
|
||||
return warnings;
|
||||
};
|
||||
|
||||
return validation;
|
||||
}
|
||||
|
||||
function TagSuggestsArea() {
|
||||
|
||||
// https://github.com/openstreetmap/josm/blob/mirror/src/org/
|
||||
// openstreetmap/josm/data/validation/tests/UnclosedWays.java#L80
|
||||
function tagSuggestsArea(tags) {
|
||||
if (_.isEmpty(tags)) return false;
|
||||
|
||||
var presence = ['landuse', 'amenities', 'tourism', 'shop'];
|
||||
for (var i = 0; i < presence.length; i++) {
|
||||
if (tags[presence[i]] !== undefined) {
|
||||
return presence[i] + '=' + tags[presence[i]];
|
||||
}
|
||||
}
|
||||
|
||||
if (tags.building && tags.building === 'yes') return 'building=yes';
|
||||
}
|
||||
|
||||
var validation = function(changes, graph) {
|
||||
var warnings = [];
|
||||
for (var i = 0; i < changes.created.length; i++) {
|
||||
var change = changes.created[i],
|
||||
geometry = change.geometry(graph),
|
||||
suggestion = (geometry === 'line' ? tagSuggestsArea(change.tags) : undefined);
|
||||
|
||||
if (suggestion) {
|
||||
warnings.push({
|
||||
id: 'tag_suggests_area',
|
||||
message: t('validations.tag_suggests_area', { tag: suggestion }),
|
||||
entity: change
|
||||
});
|
||||
}
|
||||
}
|
||||
return warnings;
|
||||
};
|
||||
|
||||
return validation;
|
||||
}
|
||||
|
||||
exports.DeprecatedTag = DeprecatedTag;
|
||||
exports.ManyDeletions = ManyDeletions;
|
||||
exports.MissingTag = MissingTag;
|
||||
exports.TagSuggestsArea = TagSuggestsArea;
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
}));
|
||||
Reference in New Issue
Block a user