X-Git-Url: https://git.openstreetmap.org./rails.git/blobdiff_plain/2f6165e040dff4231922a4d631085b6591d3b746..ce404d1afba755ca09ffb62b5d649259da503d4e:/vendor/assets/iD/iD.js?ds=sidebyside diff --git a/vendor/assets/iD/iD.js b/vendor/assets/iD/iD.js index e71d24583..2ecfaf525 100644 --- a/vendor/assets/iD/iD.js +++ b/vendor/assets/iD/iD.js @@ -7050,7 +7050,7 @@ var JXON = new (function () { /** * @license * Lo-Dash 2.3.0 (Custom Build) - * Build: `lodash include="any,assign,bind,clone,compact,contains,debounce,difference,each,every,extend,filter,find,first,forEach,groupBy,indexOf,intersection,isEmpty,isEqual,isFunction,keys,last,map,omit,pairs,pluck,reject,some,throttle,union,uniq,unique,values,without,flatten,value,chain,cloneDeep,merge" exports="global,node"` + * Build: `lodash --debug --output js/lib/lodash.js include="any,assign,bind,clone,compact,contains,debounce,difference,each,every,extend,filter,find,first,forEach,groupBy,indexOf,intersection,isEmpty,isEqual,isFunction,keys,last,map,omit,pairs,pluck,reject,some,throttle,union,uniq,unique,values,without,flatten,value,chain,cloneDeep,merge,pick" exports="global,node"` * Copyright 2012-2013 The Dojo Foundation * Based on Underscore.js 1.5.2 * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors @@ -9353,6 +9353,57 @@ var JXON = new (function () { return result; } + /** + * Creates a shallow clone of `object` composed of the specified properties. + * Property names may be specified as individual arguments or as arrays of + * property names. If a callback is provided it will be executed for each + * property of `object` picking the properties the callback returns truey + * for. The callback is bound to `thisArg` and invoked with three arguments; + * (value, key, object). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The source object. + * @param {Function|...string|string[]} [callback] The function called per + * iteration or property names to pick, specified as individual property + * names or arrays of property names. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns an object composed of the picked properties. + * @example + * + * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name'); + * // => { 'name': 'fred' } + * + * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) { + * return key.charAt(0) != '_'; + * }); + * // => { 'name': 'fred' } + */ + function pick(object, callback, thisArg) { + var result = {}; + if (typeof callback != 'function') { + var index = -1, + props = baseFlatten(arguments, true, false, 1), + length = isObject(object) ? props.length : 0; + + while (++index < length) { + var key = props[index]; + if (key in object) { + result[key] = object[key]; + } + } + } else { + callback = lodash.createCallback(callback, thisArg, 3); + forIn(object, function(value, key, object) { + if (callback(value, key, object)) { + result[key] = value; + } + }); + } + return result; + } + /** * Creates an array composed of the own enumerable property values of `object`. * @@ -10879,6 +10930,7 @@ var JXON = new (function () { lodash.merge = merge; lodash.omit = omit; lodash.pairs = pairs; + lodash.pick = pick; lodash.pluck = pluck; lodash.reject = reject; lodash.throttle = throttle; @@ -16158,52 +16210,7 @@ window.iD = function () { }; /* Projection */ - function rawMercator() { - var project = d3.geo.mercator.raw, - k = 512 / Math.PI, // scale - x = 0, y = 0, // translate - clipExtent = [[0, 0], [0, 0]]; - - function projection(point) { - point = project(point[0] * Math.PI / 180, point[1] * Math.PI / 180); - return [point[0] * k + x, y - point[1] * k]; - } - - projection.invert = function(point) { - point = project.invert((point[0] - x) / k, (y - point[1]) / k); - return point && [point[0] * 180 / Math.PI, point[1] * 180 / Math.PI]; - }; - - projection.scale = function(_) { - if (!arguments.length) return k; - k = +_; - return projection; - }; - - projection.translate = function(_) { - if (!arguments.length) return [x, y]; - x = +_[0]; - y = +_[1]; - return projection; - }; - - projection.clipExtent = function(_) { - if (!arguments.length) return clipExtent; - clipExtent = _; - return projection; - }; - - projection.stream = d3.geo.transform({ - point: function(x, y) { - x = projection([x, y]); - this.stream.point(x[0], x[1]); - } - }).stream; - - return projection; - } - - context.projection = rawMercator(); + context.projection = iD.geo.RawMercator(); /* Background */ var background = iD.Background(context); @@ -16271,7 +16278,7 @@ window.iD = function () { return d3.rebind(context, dispatch, 'on'); }; -iD.version = '1.3.10'; +iD.version = '1.4.0'; (function() { var detected = {}; @@ -16766,6 +16773,14 @@ iD.geo.edgeEqual = function(a, b) { (a[0] === b[1] && a[1] === b[0]); }; +// Return the counterclockwise angle in the range (-pi, pi) +// between the positive X axis and the line intersecting a and b. +iD.geo.angle = function(a, b, projection) { + a = projection(a.loc); + b = projection(b.loc); + return Math.atan2(b[1] - a[1], b[0] - a[0]); +}; + // Choose the edge with the minimal distance from `point` to its orthogonal // projection onto that edge, if such a projection exists, or the distance to // the closest vertex on that edge. Returns an object with the `index` of the @@ -16931,6 +16946,146 @@ _.extend(iD.geo.Extent.prototype, { return [this[0][0], this[0][1], this[1][0], this[1][1]].join(','); } }); +iD.geo.Turn = function(turn) { + if (!(this instanceof iD.geo.Turn)) + return new iD.geo.Turn(turn); + _.extend(this, turn); +}; + +iD.geo.Intersection = function(graph, vertexId) { + var vertex = graph.entity(vertexId), + highways = []; + + // Pre-split ways that would need to be split in + // order to add a restriction. The real split will + // happen when the restriction is added. + graph.parentWays(vertex).forEach(function(way) { + if (!way.tags.highway || way.isArea() || way.isDegenerate()) + return; + + if (way.affix(vertexId)) { + highways.push(way); + } else { + var idx = _.indexOf(way.nodes, vertex.id, 1), + wayA = iD.Way({id: way.id + '-a', tags: way.tags, nodes: way.nodes.slice(0, idx + 1)}), + wayB = iD.Way({id: way.id + '-b', tags: way.tags, nodes: way.nodes.slice(idx)}); + + graph = graph.replace(wayA); + graph = graph.replace(wayB); + + highways.push(wayA); + highways.push(wayB); + } + }); + + var intersection = { + highways: highways, + graph: graph + }; + + intersection.turns = function(fromNodeID) { + if (!fromNodeID) + return []; + + var way = _.find(highways, function(way) { return way.contains(fromNodeID); }); + if (way.first() === vertex.id && way.tags.oneway === 'yes') + return []; + if (way.last() === vertex.id && way.tags.oneway === '-1') + return []; + + function withRestriction(turn) { + graph.parentRelations(graph.entity(turn.from.way)).forEach(function(relation) { + if (relation.tags.type !== 'restriction') + return; + + var f = relation.memberByRole('from'), + t = relation.memberByRole('to'), + v = relation.memberByRole('via'); + + if (f && f.id === turn.from.way && + v && v.id === turn.via.node && + t && t.id === turn.to.way) { + turn.restriction = relation.id; + } else if (/^only_/.test(relation.tags.restriction) && + f && f.id === turn.from.way && + v && v.id === turn.via.node && + t && t.id !== turn.to.way) { + turn.restriction = relation.id; + turn.indirect_restriction = true; + } + }); + + return iD.geo.Turn(turn); + } + + var from = { + node: way.nodes[way.first() === vertex.id ? 1 : way.nodes.length - 2], + way: way.id.split(/-(a|b)/)[0] + }, + via = {node: vertex.id}, + turns = []; + + highways.forEach(function(parent) { + if (parent === way) + return; + + var index = parent.nodes.indexOf(vertex.id); + + // backward + if (parent.first() !== vertex.id && parent.tags.oneway !== 'yes') { + turns.push(withRestriction({ + from: from, + via: via, + to: {node: parent.nodes[index - 1], way: parent.id.split(/-(a|b)/)[0]} + })); + } + + // forward + if (parent.last() !== vertex.id && parent.tags.oneway !== '-1') { + turns.push(withRestriction({ + from: from, + via: via, + to: {node: parent.nodes[index + 1], way: parent.id.split(/-(a|b)/)[0]} + })); + } + }); + + // U-turn + if (way.tags.oneway !== 'yes' && way.tags.oneway !== '-1') { + turns.push(withRestriction({ + from: from, + via: via, + to: from, + u: true + })); + } + + return turns; + }; + + return intersection; +}; + +iD.geo.inferRestriction = function(from, via, to, projection) { + var angle = iD.geo.angle(via, from, projection) - + iD.geo.angle(via, to, projection); + + angle = angle * 180 / Math.PI; + + while (angle < 0) + angle += 360; + + if (angle < 23) + return 'no_u_turn'; + if (angle < 158) + return 'no_right_turn'; + if (angle < 202) + return 'no_straight_on'; + if (angle < 336) + return 'no_left_turn'; + + return 'no_u_turn'; +}; // For fixing up rendering of multipolygons with tags on the outer member. // https://github.com/openstreetmap/iD/issues/613 iD.geo.isSimpleMultipolygonOuterMember = function(entity, graph) { @@ -17066,67 +17221,55 @@ iD.geo.joinWays = function(array, graph) { return joined; }; -iD.geo.turns = function(graph, entityID) { - var way = graph.entity(entityID); - if (way.type !== 'way' || !way.tags.highway || way.isArea()) - return []; - - function withRestriction(turn) { - graph.parentRelations(turn.from).forEach(function(relation) { - if (relation.tags.type !== 'restriction') - return; - - var f = relation.memberByRole('from'), - t = relation.memberByRole('to'), - v = relation.memberByRole('via'); - - if (f && f.id === turn.from.id && - t && t.id === turn.to.id && - v && v.id === turn.via.id) { - turn.restriction = relation; - } - }); +/* + Bypasses features of D3's default projection stream pipeline that are unnecessary: + * Antimeridian clipping + * Spherical rotation + * Resampling +*/ +iD.geo.RawMercator = function () { + var project = d3.geo.mercator.raw, + k = 512 / Math.PI, // scale + x = 0, y = 0, // translate + clipExtent = [[0, 0], [0, 0]]; - return turn; + function projection(point) { + point = project(point[0] * Math.PI / 180, point[1] * Math.PI / 180); + return [point[0] * k + x, y - point[1] * k]; } - var turns = []; + projection.invert = function(point) { + point = project.invert((point[0] - x) / k, (y - point[1]) / k); + return point && [point[0] * 180 / Math.PI, point[1] * 180 / Math.PI]; + }; - [way.first(), way.last()].forEach(function(nodeID) { - var node = graph.entity(nodeID); - graph.parentWays(node).forEach(function(parent) { - if (parent === way || parent.isDegenerate() || !parent.tags.highway) - return; - if (way.first() === node.id && way.tags.oneway === 'yes') - return; - if (way.last() === node.id && way.tags.oneway === '-1') - return; + projection.scale = function(_) { + if (!arguments.length) return k; + k = +_; + return projection; + }; - var index = parent.nodes.indexOf(node.id); + projection.translate = function(_) { + if (!arguments.length) return [x, y]; + x = +_[0]; + y = +_[1]; + return projection; + }; - // backward - if (parent.first() !== node.id && parent.tags.oneway !== 'yes') { - turns.push(withRestriction({ - from: way, - to: parent, - via: node, - toward: graph.entity(parent.nodes[index - 1]) - })); - } + projection.clipExtent = function(_) { + if (!arguments.length) return clipExtent; + clipExtent = _; + return projection; + }; - // forward - if (parent.last() !== node.id && parent.tags.oneway !== '-1') { - turns.push(withRestriction({ - from: way, - to: parent, - via: node, - toward: graph.entity(parent.nodes[index + 1]) - })); - } - }); - }); + projection.stream = d3.geo.transform({ + point: function(x, y) { + x = projection([x, y]); + this.stream.point(x[0], x[1]); + } + }).stream; - return turns; + return projection; }; iD.actions = {}; iD.actions.AddEntity = function(way) { @@ -18172,6 +18315,95 @@ iD.actions.Orthogonalize = function(wayId, projection) { return action; }; +// Create a restriction relation for `turn`, which must have the following structure: +// +// { +// from: { node: , way: }, +// via: { node: }, +// to: { node: , way: }, +// restriction: <'no_right_turn', 'no_left_turn', etc.> +// } +// +// This specifies a restriction of type `restriction` when traveling from +// `from.node` in `from.way` toward `to.node` in `to.way` via `via.node`. +// (The action does not check that these entities form a valid intersection.) +// +// If `restriction` is not provided, it is automatically determined by the +// angle of the turn: +// +// 0-23 degrees: no_u_turn +// 23-158 degrees: no_right_turn +// 158-202 degrees: no_straight_on +// 202-326 degrees: no_left_turn +// 336-360 degrees: no_u_turn +// +// If necessary, the `from` and `to` ways are split. In these cases, `from.node` +// and `to.node` are used to determine which portion of the split ways become +// members of the restriction. +// +// For testing convenience, accepts an ID to assign to the new relation. +// Normally, this will be undefined and the relation will automatically +// be assigned a new ID. +// +iD.actions.RestrictTurn = function(turn, projection, restrictionId) { + return function(graph) { + var from = graph.entity(turn.from.way), + via = graph.entity(turn.via.node), + to = graph.entity(turn.to.way); + + function split(toOrFrom) { + var newID = toOrFrom.newID || iD.Way().id; + graph = iD.actions.Split(via.id, [newID]) + .limitWays([toOrFrom.way])(graph); + + var a = graph.entity(newID), + b = graph.entity(toOrFrom.way); + + if (a.nodes.indexOf(toOrFrom.node) !== -1) { + return [a, b]; + } else { + return [b, a]; + } + } + + if (!from.affix(via.id)) { + if (turn.from.node === turn.to.node) { + // U-turn + from = to = split(turn.from)[0]; + } else if (turn.from.way === turn.to.way) { + // Straight-on + var s = split(turn.from); + from = s[0]; + to = s[1]; + } else { + // Other + from = split(turn.from)[0]; + } + } + + if (!to.affix(via.id)) { + to = split(turn.to)[0]; + } + + return graph.replace(iD.Relation({ + id: restrictionId, + tags: { + type: 'restriction', + restriction: turn.restriction || + iD.geo.inferRestriction( + graph.entity(turn.from.node), + via, + graph.entity(turn.to.node), + projection) + }, + members: [ + {id: from.id, type: 'way', role: 'from'}, + {id: via.id, type: 'node', role: 'via'}, + {id: to.id, type: 'way', role: 'to'} + ] + })); + }; +}; /* Order the nodes of a way in reverse order and reverse any direction dependent tags other than `oneway`. (We assume that correcting a backwards oneway is the primary @@ -18546,6 +18778,29 @@ iD.actions.Straighten = function(wayId, projection) { return action; }; +// Remove the effects of `turn.restriction` on `turn`, which must have the +// following structure: +// +// { +// from: { node: , way: }, +// via: { node: }, +// to: { node: , way: }, +// restriction: +// } +// +// In the simple case, `restriction` is a reference to a `no_*` restriction +// on the turn itself. In this case, it is simply deleted. +// +// The more complex case is where `restriction` references an `only_*` +// restriction on a different turn in the same intersection. In that case, +// that restriction is also deleted, but at the same time restrictions on +// the turns other than the first two are created. +// +iD.actions.UnrestrictTurn = function(turn) { + return function(graph) { + return iD.actions.DeleteRelation(turn.restriction)(graph); + }; +}; iD.behavior = {}; iD.behavior.AddWay = function(context) { var event = d3.dispatch('start', 'startFromWay', 'startFromNode'), @@ -19349,8 +19604,6 @@ iD.behavior.Lasso = function(context) { .on('mouseup.lasso', mouseup); d3.event.stopPropagation(); - d3.event.preventDefault(); - } } @@ -20692,15 +20945,15 @@ iD.operations.Delete = function(selectedIDs, context) { } } - context.perform( - action, - annotation); - 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() { @@ -21339,7 +21592,7 @@ iD.areaKeys = { connection.changesetTags = function(comment, imageryUsed) { var tags = { - imagery_used: imageryUsed.join(';'), + imagery_used: imageryUsed.join(';').substr(0, 255), created_by: 'iD ' + iD.version }; @@ -21821,6 +22074,10 @@ iD.Entity.prototype = { }); }, + isHighwayIntersection: function() { + return false; + }, + deprecatedTags: function() { var tags = _.pairs(this.tags); var deprecated = {}; @@ -22469,6 +22726,14 @@ _.extend(iD.Node.prototype, { }); }, + isHighwayIntersection: function(resolver) { + return resolver.transient(this, 'isHighwayIntersection', function() { + return resolver.parentWays(this).filter(function(parent) { + return parent.tags.highway && parent.geometry(resolver) === 'line'; + }).length > 1; + }); + }, + asJXON: function(changeset_id) { var r = { node: { @@ -22492,6 +22757,38 @@ _.extend(iD.Node.prototype, { }; } }); +iD.oneWayTags = { + 'aerialway': { + 'chair_lift': true, + 'mixed_lift': true, + 't-bar': true, + 'j-bar': true, + 'platter': true, + 'rope_tow': true, + 'magic_carpet': true, + 'yes': true + }, + 'highway': { + 'motorway': true, + 'motorway_link': true + }, + 'junction': { + 'roundabout': true + }, + 'man_made': { + 'piste:halfpipe': true, + 'pipeline': true + }, + 'piste:type': { + 'downhill': true, + 'sled': true, + 'yes': true + }, + 'waterway': { + 'river': true, + 'stream': true + } +}; iD.Relation = iD.Entity.relation = function iD_Relation() { if (!(this instanceof iD_Relation)) { return (new iD_Relation()).initialize(arguments); @@ -22886,11 +23183,11 @@ _.extend(iD.Way.prototype, { if (['no', '0'].indexOf(this.tags.oneway) !== -1) { return false; } // implied oneway tag.. - return this.tags.waterway === 'river' || - this.tags.waterway === 'stream' || - this.tags.highway === 'motorway' || - this.tags.highway === 'motorway_link' || - this.tags.junction === 'roundabout'; + for (var key in this.tags) { + if (key in iD.oneWayTags && (this.tags[key] in iD.oneWayTags[key])) + return true; + } + return false; }, isClosed: function() { @@ -23641,30 +23938,7 @@ iD.Map = function(context) { if (difference) { var complete = difference.complete(map.extent()); all = _.compact(_.values(complete)); - filter = function(d) { - if (d.type === 'midpoint') { - - var a = d.edge[0], - b = d.edge[1]; - - // redraw a midpoint if it needs to be - // - moved (either edge node moved) - // - deleted (edge nodes not consecutive in any parent way) - if (a in complete || b in complete) return true; - - var parentsWays = graph.parentWays({ id: a }); - for (var i = 0; i < parentsWays.length; i++) { - var nodes = parentsWays[i].nodes; - for (var n = 0; n < nodes.length; n++) { - if (nodes[n] === a && (nodes[n - 1] === b || nodes[n + 1] === b)) return false; - } - } - return true; - - } else { - return d.id in complete; - } - }; + filter = function(d) { return d.id in complete; }; } else if (extent) { all = context.intersects(map.extent().intersection(extent)); @@ -24337,6 +24611,135 @@ iD.svg.Areas = function(projection) { .attr('d', path); }; }; +/* + A standalone SVG element that contains only a `defs` sub-element. To be + used once globally, since defs IDs must be unique within a document. +*/ +iD.svg.Defs = function(context) { + function autosize(image) { + var img = document.createElement('img'); + img.src = image.attr('xlink:href'); + img.onload = function() { + image.attr({ + width: img.width, + height: img.height + }); + }; + } + + function SpriteDefinition(id, href, data) { + return function(defs) { + defs.append('image') + .attr('id', id) + .attr('xlink:href', href) + .call(autosize); + + defs.selectAll() + .data(data) + .enter().append('use') + .attr('id', function(d) { return d.key; }) + .attr('transform', function(d) { return 'translate(-' + d.value[0] + ',-' + d.value[1] + ')'; }) + .attr('xlink:href', '#' + id); + }; + } + + return function (selection) { + var defs = selection.append('defs'); + + defs.append('marker') + .attr({ + id: 'oneway-marker', + viewBox: '0 0 10 10', + refY: 2.5, + refX: 5, + markerWidth: 2, + markerHeight: 2, + orient: 'auto' + }) + .append('path') + .attr('d', 'M 5 3 L 0 3 L 0 2 L 5 2 L 5 0 L 10 2.5 L 5 5 z'); + + var patterns = defs.selectAll('pattern') + .data([ + // pattern name, pattern image name + ['wetland', 'wetland'], + ['construction', 'construction'], + ['cemetery', 'cemetery'], + ['orchard', 'orchard'], + ['farmland', 'farmland'], + ['beach', 'dots'], + ['scrub', 'dots'], + ['meadow', 'dots'] + ]) + .enter() + .append('pattern') + .attr({ + id: function (d) { + return 'pattern-' + d[0]; + }, + width: 32, + height: 32, + patternUnits: 'userSpaceOnUse' + }); + + patterns.append('rect') + .attr({ + x: 0, + y: 0, + width: 32, + height: 32, + 'class': function (d) { + return 'pattern-color-' + d[0]; + } + }); + + patterns.append('image') + .attr({ + x: 0, + y: 0, + width: 32, + height: 32 + }) + .attr('xlink:href', function (d) { + return context.imagePath('pattern/' + d[1] + '.png'); + }); + + defs.selectAll() + .data([12, 18, 20, 32, 45]) + .enter().append('clipPath') + .attr('id', function (d) { + return 'clip-square-' + d; + }) + .append('rect') + .attr('x', 0) + .attr('y', 0) + .attr('width', function (d) { + return d; + }) + .attr('height', function (d) { + return d; + }); + + var maki = []; + _.forEach(iD.data.featureIcons, function (dimensions, name) { + if (dimensions['12'] && dimensions['18'] && dimensions['24']) { + maki.push({key: 'maki-' + name + '-12', value: dimensions['12']}); + maki.push({key: 'maki-' + name + '-18', value: dimensions['18']}); + maki.push({key: 'maki-' + name + '-24', value: dimensions['24']}); + } + }); + + defs.call(SpriteDefinition( + 'sprite', + context.imagePath('sprite.svg'), + d3.entries(iD.data.operations))); + + defs.call(SpriteDefinition( + 'maki-sprite', + context.imagePath('maki-sprite.png'), + maki)); + }; +}; iD.svg.Labels = function(projection, context) { var path = d3.geo.path().projection(projection); @@ -24891,39 +25294,50 @@ iD.svg.Midpoints = function(projection, context) { for (var i = 0; i < entities.length; i++) { var entity = entities[i]; - if (entity.type !== 'way') continue; - if (context.selectedIDs().indexOf(entity.id) < 0) continue; + if (entity.type !== 'way') + continue; + if (!filter(entity)) + continue; + if (context.selectedIDs().indexOf(entity.id) < 0) + continue; var nodes = graph.childNodes(entity); - - // skip the last node because it is always repeated for (var j = 0; j < nodes.length - 1; j++) { var a = nodes[j], b = nodes[j + 1], id = [a.id, b.id].sort().join('-'); - // Redraw midpoints in two cases: - // 1. One of the two endpoint nodes changed (e.g. was moved). - // 2. A node was deleted. The midpoint between the two new - // endpoints needs to be redrawn. In this case only the - // way will be in the diff. - if (!midpoints[id] && (filter(a) || filter(b) || filter(entity))) { + if (midpoints[id]) { + midpoints[id].parents.push(entity); + } else { var loc = iD.geo.interp(a.loc, b.loc, 0.5); if (extent.intersects(loc) && iD.geo.euclideanDistance(projection(a.loc), projection(b.loc)) > 40) { midpoints[id] = { type: 'midpoint', id: id, loc: loc, - edge: [a.id, b.id] + edge: [a.id, b.id], + parents: [entity] }; } } } } + function midpointFilter(d) { + if (midpoints[d.id]) + return true; + + for (var i = 0; i < d.parents.length; i++) + if (filter(d.parents[i])) + return true; + + return false; + } + var groups = surface.select('.layer-hit').selectAll('g.midpoint') - .filter(filter) + .filter(midpointFilter) .data(_.values(midpoints), function(d) { return d.id; }); var group = groups.enter() @@ -25017,192 +25431,8 @@ iD.svg.Points = function(projection, context) { return drawPoints; }; -iD.svg.Restrictions = function(context) { - var projection = context.projection; - - function drawRestrictions(surface) { - var turns = drawRestrictions.turns(context.graph(), context.selectedIDs()); - - var groups = surface.select('.layer-hit').selectAll('g.restriction') - .data(turns, iD.Entity.key); - - var enter = groups.enter().append('g') - .attr('class', 'restriction'); - - enter.append('circle') - .attr('class', 'restriction') - .attr('r', 4); - - groups - .attr('transform', function(restriction) { - var via = context.entity(restriction.memberByRole('via').id); - return iD.svg.PointTransform(projection)(via); - }); - - groups.exit() - .remove(); - - return this; - } - - drawRestrictions.turns = function (graph, selectedIDs) { - if (selectedIDs.length !== 1) - return []; - - var from = graph.entity(selectedIDs[0]); - if (from.type !== 'way') - return []; - - return graph.parentRelations(from).filter(function(relation) { - var f = relation.memberById(from.id), - t = relation.memberByRole('to'), - v = relation.memberByRole('via'); - - return relation.tags.type === 'restriction' && f.role === 'from' && - t && t.type === 'way' && graph.hasEntity(t.id) && - v && v.type === 'node' && graph.hasEntity(v.id) && - !graph.entity(t.id).isDegenerate() && - !graph.entity(f.id).isDegenerate() && - graph.entity(t.id).affix(v.id) && - graph.entity(f.id).affix(v.id); - }); - }; - - drawRestrictions.datum = function(graph, from, restriction, projection) { - var to = graph.entity(restriction.memberByRole('to').id), - a = graph.entity(restriction.memberByRole('via').id), - b; - - if (to.first() === a.id) { - b = graph.entity(to.nodes[1]); - } else { - b = graph.entity(to.nodes[to.nodes.length - 2]); - } - - a = projection(a.loc); - b = projection(b.loc); - - return { - from: from, - to: to, - restriction: restriction, - angle: Math.atan2(b[1] - a[1], b[0] - a[0]) - }; - }; - - return drawRestrictions; -}; -iD.svg.Surface = function(context) { - function autosize(image) { - var img = document.createElement('img'); - img.src = image.attr('xlink:href'); - img.onload = function() { - image.attr({ - width: img.width, - height: img.height - }); - }; - } - - function SpriteDefinition(id, href, data) { - return function(defs) { - defs.append('image') - .attr('id', id) - .attr('xlink:href', href) - .call(autosize); - - defs.selectAll() - .data(data) - .enter().append('use') - .attr('id', function(d) { return d.key; }) - .attr('transform', function(d) { return 'translate(-' + d.value[0] + ',-' + d.value[1] + ')'; }) - .attr('xlink:href', '#' + id); - }; - } - - return function drawSurface(selection) { - var defs = selection.append('defs'); - - defs.append('marker') - .attr({ - id: 'oneway-marker', - viewBox: '0 0 10 10', - refY: 2.5, - refX: 5, - markerWidth: 2, - markerHeight: 2, - orient: 'auto' - }) - .append('path') - .attr('d', 'M 5 3 L 0 3 L 0 2 L 5 2 L 5 0 L 10 2.5 L 5 5 z'); - - var patterns = defs.selectAll('pattern') - .data([ - // pattern name, pattern image name - ['wetland', 'wetland'], - ['construction', 'construction'], - ['cemetery', 'cemetery'], - ['orchard', 'orchard'], - ['farmland', 'farmland'], - ['beach', 'dots'], - ['scrub', 'dots'], - ['meadow', 'dots']]) - .enter() - .append('pattern') - .attr({ - id: function(d) { return 'pattern-' + d[0]; }, - width: 32, - height: 32, - patternUnits: 'userSpaceOnUse' - }); - - patterns.append('rect') - .attr({ - x: 0, - y: 0, - width: 32, - height: 32, - 'class': function(d) { return 'pattern-color-' + d[0]; } - }); - - patterns.append('image') - .attr({ - x: 0, - y: 0, - width: 32, - height: 32 - }) - .attr('xlink:href', function(d) { return context.imagePath('pattern/' + d[1] + '.png'); }); - - defs.selectAll() - .data([12, 18, 20]) - .enter().append('clipPath') - .attr('id', function(d) { return 'clip-square-' + d; }) - .append('rect') - .attr('x', 0) - .attr('y', 0) - .attr('width', function(d) { return d; }) - .attr('height', function(d) { return d; }); - - var maki = []; - _.forEach(iD.data.featureIcons, function(dimensions, name) { - if (dimensions['12'] && dimensions['18'] && dimensions['24']) { - maki.push({key: 'maki-' + name + '-12', value: dimensions['12']}); - maki.push({key: 'maki-' + name + '-18', value: dimensions['18']}); - maki.push({key: 'maki-' + name + '-24', value: dimensions['24']}); - } - }); - - defs.call(SpriteDefinition( - 'sprite', - context.imagePath('sprite.svg'), - d3.entries(iD.data.operations))); - - defs.call(SpriteDefinition( - 'maki-sprite', - context.imagePath('maki-sprite.png'), - maki)); - +iD.svg.Surface = function() { + return function (selection) { var layers = selection.selectAll('.layer') .data(['fill', 'shadow', 'casing', 'stroke', 'oneway', 'hit', 'halo', 'label']); @@ -25265,6 +25495,77 @@ iD.svg.TagClasses = function() { return tagClasses; }; +iD.svg.Turns = function(projection) { + return function(surface, graph, turns) { + function key(turn) { + return [turn.from.node + turn.via.node + turn.to.node].join('-'); + } + + function icon(turn) { + var u = turn.u ? '-u' : ''; + if (!turn.restriction) + return '#icon-restriction-yes' + u; + var restriction = graph.entity(turn.restriction).tags.restriction; + return '#icon-restriction-' + + (!turn.indirect_restriction && /^only_/.test(restriction) ? 'only' : 'no') + u; + } + + var groups = surface.select('.layer-hit').selectAll('g.turn') + .data(turns, key); + + // Enter + + var enter = groups.enter().append('g') + .attr('class', 'turn'); + + var nEnter = enter.filter(function (turn) { return !turn.u; }); + + nEnter.append('rect') + .attr('transform', 'translate(-12, -12)') + .attr('width', '45') + .attr('height', '25'); + + nEnter.append('use') + .attr('transform', 'translate(-12, -12)') + .attr('clip-path', 'url(#clip-square-45)'); + + var uEnter = enter.filter(function (turn) { return turn.u; }); + + uEnter.append('circle') + .attr('r', '16'); + + uEnter.append('use') + .attr('transform', 'translate(-16, -16)') + .attr('clip-path', 'url(#clip-square-32)'); + + // Update + + groups + .attr('transform', function (turn) { + var v = graph.entity(turn.via.node), + t = graph.entity(turn.to.node), + a = iD.geo.angle(v, t, projection), + p = projection(v.loc), + r = turn.u ? 0 : 60; + + return 'translate(' + (r * Math.cos(a) + p[0]) + ',' + (r * Math.sin(a) + p[1]) + ')' + + 'rotate(' + a * 180 / Math.PI + ')'; + }); + + groups.select('use') + .attr('xlink:href', icon); + + groups.select('rect'); + groups.select('circle'); + + // Exit + + groups.exit() + .remove(); + + return this; + }; +}; iD.svg.Vertices = function(projection, context) { var radiuses = { // z16-, z17, z18+, tagged @@ -25429,6 +25730,10 @@ iD.ui = function(context) { map.centerZoom([-77.02271, 38.90085], 20); } + container.append('svg') + .attr('id', 'defs') + .call(iD.svg.Defs(context)); + container.append('div') .attr('id', 'sidebar') .attr('class', 'col4') @@ -26491,6 +26796,8 @@ iD.ui.EntityEditor = function(context) { preset, reference; + var presetEditor = iD.ui.preset(context) + .on('change', changeTags); var rawTagEditor = iD.ui.RawTagEditor(context) .on('change', changeTags); @@ -26577,12 +26884,11 @@ iD.ui.EntityEditor = function(context) { .text(preset.name()); $body.select('.inspector-preset') - .call(iD.ui.preset(context) + .call(presetEditor .preset(preset) .entityID(id) .tags(tags) - .state(state) - .on('change', changeTags)); + .state(state)); $body.select('.raw-tag-editor') .call(rawTagEditor @@ -26619,11 +26925,13 @@ iD.ui.EntityEditor = function(context) { function clean(o) { var out = {}, k, v; + /*jshint -W083 */ for (k in o) { if (k && (v = o[k]) !== undefined) { - out[k] = v.trim(); + out[k] = v.split(';').map(function(s) { return s.trim(); }).join(';'); } } + /*jshint +W083 */ return out; } @@ -27141,7 +27449,12 @@ iD.ui.Inspector = function(context) { var $presetPane = $wrap.select('.preset-list-pane'); var $editorPane = $wrap.select('.entity-editor-pane'); - var showEditor = state === 'hover' || context.entity(entityID).isUsed(context.graph()); + var graph = context.graph(), + entity = context.entity(entityID), + showEditor = state === 'hover' || + entity.isUsed(graph) || + entity.isHighwayIntersection(graph); + if (showEditor) { $wrap.style('right', '0%'); $editorPane.call(entityEditor); @@ -27669,6 +27982,10 @@ iD.ui.preset = function(context) { } }); + if (entity.isHighwayIntersection(context.graph())) { + fields.push(UIField(context.presets().field('restrictions'), entity, true)); + } + context.presets().universal().forEach(function(field) { if (preset.fields.indexOf(field) < 0) { fields.push(UIField(field, entity)); @@ -27774,7 +28091,7 @@ iD.ui.preset = function(context) { function show(field) { field.show = true; - presets(selection); + context.presets()(selection); field.input.focus(); } @@ -27793,6 +28110,7 @@ iD.ui.preset = function(context) { presets.preset = function(_) { if (!arguments.length) return preset; + if (preset && preset.id === _.id) return presets; preset = _; fields = null; return presets; @@ -27813,6 +28131,7 @@ iD.ui.preset = function(context) { presets.entityID = function(_) { if (!arguments.length) return id; + if (id === _) return presets; id = _; fields = null; return presets; @@ -29054,6 +29373,7 @@ iD.ui.Sidebar = function(context) { sidebar.hide = function() { featureListWrap.classed('inspector-hidden', false); + inspectorWrap.classed('inspector-hidden', true); if (current) current.remove(); current = null; }; @@ -29883,10 +30203,6 @@ iD.ui.preset.address = function(field, context) { city = wrap.select('.addr-city'); postcode = wrap.select('.addr-postcode'); - wrap.selectAll('input') - .on('blur', change) - .on('change', change); - street .call(d3.combobox() .fetcher(function(value, callback) { @@ -29904,6 +30220,10 @@ iD.ui.preset.address = function(field, context) { .fetcher(function(value, callback) { callback(getPostCodes()); })); + + wrap.selectAll('input') + .on('blur', change) + .on('change', change); } function change() { @@ -29937,15 +30257,38 @@ iD.ui.preset.address = function(field, context) { iD.ui.preset.check = iD.ui.preset.defaultcheck = function(field) { var event = d3.dispatch('change'), - values = field.type === 'check' ? - [undefined, 'yes', 'no'] : - [undefined, 'yes'], - value, - box, - text, - label; + options = field.strings && field.strings.options, + values = [], + texts = [], + entity, value, box, text, label; + + if (options) { + for (var k in options) { + values.push(k === 'undefined' ? undefined : k); + texts.push(field.t('check.' + k, { 'default': options[k] })); + } + } else { + values = [undefined, 'yes']; + texts = [t('inspector.unknown'), t('inspector.check.yes')]; + if (field.type === 'check') { + values.push('no'); + texts.push(t('inspector.check.no')); + } + } var check = function(selection) { + // hack: pretend oneway field is a oneway_yes field + // where implied oneway tag exists (e.g. `junction=roundabout`) #2220, #1841 + if (field.id === 'oneway') { + for (var key in entity.tags) { + if (key in iD.oneWayTags && (entity.tags[key] in iD.oneWayTags[key])) { + texts.shift(); + texts.unshift(t('presets.fields.oneway_yes.check.undefined', { 'default': 'Assumed to be Yes' })); + break; + } + } + } + selection.classed('checkselect', 'true'); label = selection.selectAll('.preset-input-wrap') @@ -29960,7 +30303,7 @@ iD.ui.preset.defaultcheck = function(field) { .attr('id', 'preset-input-' + field.id); enter.append('span') - .text(t('inspector.unknown')) + .text(texts[0]) .attr('class', 'value'); box = label.select('input') @@ -29974,12 +30317,17 @@ iD.ui.preset.defaultcheck = function(field) { text = label.select('span.value'); }; + check.entity = function(_) { + if (!arguments.length) return entity; + entity = _; + return check; + }; + check.tags = function(tags) { value = tags[field.key]; box.property('indeterminate', field.type === 'check' && !value); box.property('checked', value === 'yes'); - text.text(value ? t('inspector.check.' + value, {default: value}) : - field.type === 'check' ? t('inspector.unknown') : t('inspector.check.no')); + text.text(texts[values.indexOf(value)]); label.classed('set', !!value); }; @@ -30005,6 +30353,7 @@ iD.ui.preset.typeCombo = function(field) { .attr('id', 'preset-input-' + field.id); input + .call(combobox) .on('change', change) .on('blur', change) .each(function() { @@ -30017,13 +30366,12 @@ iD.ui.preset.typeCombo = function(field) { if (!err) options(_.pluck(data, 'value')); }); } - }) - .call(combobox); + }); function options(opts) { combobox.data(opts.map(function(d) { var o = {}; - o.title = o.value = d.replace('_', ' '); + o.title = o.value = d.replace(/_+/g, ' '); return o; })); @@ -30035,7 +30383,12 @@ iD.ui.preset.typeCombo = function(field) { } function change() { - var value = input.value().replace(' ', '_'); + var value = input.value() + .split(';') + .map(function(s) { return s.trim(); }) + .join(';') + .replace(/\s+/g, '_'); + if (field.type === 'typeCombo' && !value) value = 'yes'; var t = {}; @@ -30137,10 +30490,6 @@ iD.ui.preset.localized = function(field, context) { .attr('class', 'localized-main') .attr('placeholder', field.placeholder()); - input - .on('blur', change) - .on('change', change); - if (field.id === 'name') { var preset = context.presets().match(entity, context.graph()); input.call(d3.combobox().fetcher( @@ -30148,6 +30497,10 @@ iD.ui.preset.localized = function(field, context) { )); } + input + .on('blur', change) + .on('change', change); + var translateButton = selection.selectAll('.localized-add') .data([0]); @@ -30377,9 +30730,9 @@ iD.ui.preset.maxspeed = function(field, context) { .attr('placeholder', field.placeholder()); input + .call(combobox) .on('change', change) - .on('blur', change) - .call(combobox); + .on('blur', change); var childNodes = context.graph().childNodes(context.entity(entity.id)), loc = childNodes[~~(childNodes.length/2)].loc; @@ -30539,6 +30892,145 @@ iD.ui.preset.radio = function(field) { return d3.rebind(radio, event, 'on'); }; +iD.ui.preset.restrictions = function(field, context) { + var event = d3.dispatch('change'), + vertexID, + fromNodeID; + + function restrictions(selection) { + var wrap = selection.selectAll('.preset-input-wrap') + .data([0]); + + var enter = wrap.enter().append('div') + .attr('class', 'preset-input-wrap'); + + enter.append('div') + .attr('class', 'restriction-help'); + + enter.append('svg') + .call(iD.svg.Surface(context)) + .call(iD.behavior.Hover(context)); + + var intersection = iD.geo.Intersection(context.graph(), vertexID), + graph = intersection.graph, + vertex = graph.entity(vertexID), + surface = wrap.selectAll('svg'), + filter = function () { return true; }, + extent = iD.geo.Extent(), + projection = iD.geo.RawMercator(), + lines = iD.svg.Lines(projection, context), + vertices = iD.svg.Vertices(projection, context), + turns = iD.svg.Turns(projection, context); + + var d = wrap.dimensions(), + c = [d[0] / 2, d[1] / 2], + z = 21; + + projection + .scale(256 * Math.pow(2, z) / (2 * Math.PI)); + + var s = projection(vertex.loc); + + projection + .translate([c[0] - s[0], c[1] - s[1]]) + .clipExtent([[0, 0], d]); + + surface + .call(vertices, graph, [vertex], filter, extent, z) + .call(lines, graph, intersection.highways, filter) + .call(turns, graph, intersection.turns(fromNodeID)); + + surface + .on('click.restrictions', click) + .on('mouseover.restrictions', mouseover) + .on('mouseout.restrictions', mouseout); + + surface + .selectAll('.selected') + .classed('selected', false); + + if (fromNodeID) { + surface + .selectAll('.' + _.find(intersection.highways, function(way) { return way.contains(fromNodeID); }).id) + .classed('selected', true); + } + + mouseout(); + + context.history() + .on('change.restrictions', render); + + d3.select(window) + .on('resize.restrictions', render); + + function click() { + var datum = d3.event.target.__data__; + if (datum instanceof iD.Entity) { + fromNodeID = datum.nodes[(datum.first() === vertexID) ? 1 : datum.nodes.length - 2]; + render(); + } else if (datum instanceof iD.geo.Turn) { + if (datum.restriction) { + context.perform( + iD.actions.UnrestrictTurn(datum, projection), + t('operations.restriction.annotation.delete')); + } else { + context.perform( + iD.actions.RestrictTurn(datum, projection), + t('operations.restriction.annotation.create')); + } + } + } + + function mouseover() { + var datum = d3.event.target.__data__; + if (datum instanceof iD.geo.Turn) { + var graph = context.graph(), + presets = context.presets(), + preset; + + if (datum.restriction) { + preset = presets.match(graph.entity(datum.restriction), graph); + } else { + preset = presets.item('type/restriction/' + + iD.geo.inferRestriction( + graph.entity(datum.from.node), + graph.entity(datum.via.node), + graph.entity(datum.to.node), + projection)); + } + + wrap.selectAll('.restriction-help') + .text(t('operations.restriction.help.' + + (datum.restriction ? 'toggle_off' : 'toggle_on'), + {restriction: preset.name()})); + } + } + + function mouseout() { + wrap.selectAll('.restriction-help') + .text(t('operations.restriction.help.' + + (fromNodeID ? 'toggle' : 'select'))); + } + + function render() { + if (context.hasEntity(vertexID)) { + restrictions(selection); + } + } + } + + restrictions.entity = function(_) { + if (!vertexID || vertexID !== _.id) { + fromNodeID = null; + vertexID = _.id; + } + }; + + restrictions.tags = function() {}; + restrictions.focus = function() {}; + + return d3.rebind(restrictions, event, 'on'); +}; iD.ui.preset.textarea = function(field) { var event = d3.dispatch('change'), @@ -30617,9 +31109,9 @@ iD.ui.preset.wikipedia = function(field, context) { .value('English'); lang + .call(langcombo) .on('blur', changeLang) - .on('change', changeLang) - .call(langcombo); + .on('change', changeLang); title = selection.selectAll('input.wiki-title') .data([0]); @@ -30630,9 +31122,9 @@ iD.ui.preset.wikipedia = function(field, context) { .attr('id', 'preset-input-' + field.id); title + .call(titlecombo) .on('blur', change) - .on('change', change) - .call(titlecombo); + .on('change', change); link = selection.selectAll('a.wiki-link') .data([0]); @@ -31483,7 +31975,7 @@ iD.presets.Field = function(id, field) { field.id = id; field.matchGeometry = function(geometry) { - return !field.geometry || field.geometry.indexOf(geometry) >= 0; + return !field.geometry || field.geometry === geometry; }; field.t = function(scope, options) { @@ -63760,6 +64252,26 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," "opening_hours" ] }, + "amenity/dojo": { + "icon": "pitch", + "geometry": [ + "point", + "area" + ], + "terms": [ + "martial arts", + "dojo", + "dojang" + ], + "tags": { + "amenity": "dojo" + }, + "fields": [ + "address", + "sport" + ], + "name": "Dojo / Martial Arts Academy" + }, "amenity/drinking_water": { "icon": "water", "geometry": [ @@ -66504,7 +67016,9 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," "fields": [ "crossing", "access", - "surface" + "surface", + "sloped_curb", + "tactile_paving" ], "geometry": [ "line" @@ -66513,11 +67027,30 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," "highway": "footway", "footway": "crossing" }, + "terms": [], + "name": "Crossing" + }, + "footway/crosswalk": { + "fields": [ + "crossing", + "access", + "surface", + "sloped_curb", + "tactile_paving" + ], + "geometry": [ + "line" + ], + "tags": { + "highway": "footway", + "footway": "crossing", + "crossing": "zebra" + }, "terms": [ "crosswalk", "zebra crossing" ], - "name": "Crossing" + "name": "Crosswalk" }, "footway/sidewalk": { "fields": [ @@ -66718,11 +67251,27 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," "tags": { "highway": "crossing" }, + "terms": [], + "name": "Crossing" + }, + "highway/crosswalk": { + "fields": [ + "crossing", + "sloped_curb", + "tactile_paving" + ], + "geometry": [ + "vertex" + ], + "tags": { + "highway": "crossing", + "crossing": "zebra" + }, "terms": [ "crosswalk", "zebra crossing" ], - "name": "Crossing" + "name": "Crosswalk" }, "highway/cycleway": { "icon": "highway-cycleway", @@ -66819,7 +67368,7 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," "highway/motorway": { "icon": "highway-motorway", "fields": [ - "oneway", + "oneway_yes", "maxspeed", "structure", "access", @@ -66846,7 +67395,7 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," "fields": [ "ref" ], - "name": "Motorway Junction" + "name": "Motorway Junction / Exit" }, "highway/motorway_link": { "icon": "highway-motorway-link", @@ -68042,6 +68591,7 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," "name": "Slipway" }, "leisure/sports_center": { + "icon": "pitch", "geometry": [ "point", "area" @@ -68052,10 +68602,13 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," "terms": [ "gym" ], - "icon": "sports", - "name": "Sports Center" + "fields": [ + "sport" + ], + "name": "Sports Center / Gym" }, "leisure/stadium": { + "icon": "pitch", "geometry": [ "point", "area" @@ -70984,9 +71537,108 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," "name": "Restriction", "icon": "restriction", "fields": [ - "restriction" + "restriction", + "except" ] }, + "type/restriction/no_left_turn": { + "name": "No Left Turn", + "geometry": [ + "relation" + ], + "tags": { + "type": "restriction", + "restriction": "no_left_turn" + }, + "fields": [ + "except" + ], + "icon": "restriction-no-left-turn" + }, + "type/restriction/no_right_turn": { + "name": "No Right Turn", + "geometry": [ + "relation" + ], + "tags": { + "type": "restriction", + "restriction": "no_right_turn" + }, + "fields": [ + "except" + ], + "icon": "restriction-no-right-turn" + }, + "type/restriction/no_straight_on": { + "name": "No Straight On", + "geometry": [ + "relation" + ], + "tags": { + "type": "restriction", + "restriction": "no_straight_on" + }, + "fields": [ + "except" + ], + "icon": "restriction-no-straight-on" + }, + "type/restriction/no_u_turn": { + "name": "No U-turn", + "geometry": [ + "relation" + ], + "tags": { + "type": "restriction", + "restriction": "no_u_turn" + }, + "fields": [ + "except" + ], + "icon": "restriction-no-u-turn" + }, + "type/restriction/only_left_turn": { + "name": "Left Turn Only", + "geometry": [ + "relation" + ], + "tags": { + "type": "restriction", + "restriction": "only_left_turn" + }, + "fields": [ + "except" + ], + "icon": "restriction-only-left-turn" + }, + "type/restriction/only_right_turn": { + "name": "Right Turn Only", + "geometry": [ + "relation" + ], + "tags": { + "type": "restriction", + "restriction": "only_right_turn" + }, + "fields": [ + "except" + ], + "icon": "restriction-only-right-turn" + }, + "type/restriction/only_straight_on": { + "name": "No Turns", + "geometry": [ + "relation" + ], + "tags": { + "type": "restriction", + "restriction": "only_straight_on" + }, + "fields": [ + "except" + ], + "icon": "restriction-only-straight-on" + }, "type/route": { "geometry": [ "relation" @@ -71597,25 +72249,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "amenity/fuel/Sainsbury's": { - "tags": { - "name": "Sainsbury's", - "amenity": "fuel" - }, - "name": "Sainsbury's", - "icon": "fuel", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "operator", - "address", - "building_area" - ], - "suggestion": true - }, "amenity/fuel/OMV": { "tags": { "name": "OMV", @@ -71654,25 +72287,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "amenity/fuel/Tesco": { - "tags": { - "name": "Tesco", - "amenity": "fuel" - }, - "name": "Tesco", - "icon": "fuel", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "operator", - "address", - "building_area" - ], - "suggestion": true - }, "amenity/fuel/JET": { "tags": { "name": "JET", @@ -71692,25 +72306,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "amenity/fuel/Morrisons": { - "tags": { - "name": "Morrisons", - "amenity": "fuel" - }, - "name": "Morrisons", - "icon": "fuel", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "operator", - "address", - "building_area" - ], - "suggestion": true - }, "amenity/fuel/United": { "tags": { "name": "United", @@ -71730,25 +72325,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "amenity/fuel/Canadian Tire": { - "tags": { - "name": "Canadian Tire", - "amenity": "fuel" - }, - "name": "Canadian Tire", - "icon": "fuel", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "operator", - "address", - "building_area" - ], - "suggestion": true - }, "amenity/fuel/Mobil": { "tags": { "name": "Mobil", @@ -71825,25 +72401,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "amenity/fuel/ABC": { - "tags": { - "name": "ABC", - "amenity": "fuel" - }, - "name": "ABC", - "icon": "fuel", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "operator", - "address", - "building_area" - ], - "suggestion": true - }, "amenity/fuel/ARAL": { "tags": { "name": "ARAL", @@ -71920,25 +72477,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "amenity/fuel/Intermarché": { - "tags": { - "name": "Intermarché", - "amenity": "fuel" - }, - "name": "Intermarché", - "icon": "fuel", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "operator", - "address", - "building_area" - ], - "suggestion": true - }, "amenity/fuel/Total Access": { "tags": { "name": "Total Access", @@ -71958,44 +72496,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "amenity/fuel/Super U": { - "tags": { - "name": "Super U", - "amenity": "fuel" - }, - "name": "Super U", - "icon": "fuel", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "operator", - "address", - "building_area" - ], - "suggestion": true - }, - "amenity/fuel/Auchan": { - "tags": { - "name": "Auchan", - "amenity": "fuel" - }, - "name": "Auchan", - "icon": "fuel", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "operator", - "address", - "building_area" - ], - "suggestion": true - }, "amenity/fuel/Elf": { "tags": { "name": "Elf", @@ -72015,25 +72515,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "amenity/fuel/Carrefour": { - "tags": { - "name": "Carrefour", - "amenity": "fuel" - }, - "name": "Carrefour", - "icon": "fuel", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "operator", - "address", - "building_area" - ], - "suggestion": true - }, "amenity/fuel/Station Service E. Leclerc": { "tags": { "name": "Station Service E. Leclerc", @@ -72376,25 +72857,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "amenity/fuel/Raiffeisenbank": { - "tags": { - "name": "Raiffeisenbank", - "amenity": "fuel" - }, - "name": "Raiffeisenbank", - "icon": "fuel", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "operator", - "address", - "building_area" - ], - "suggestion": true - }, "amenity/fuel/Tamoil": { "tags": { "name": "Tamoil", @@ -72490,25 +72952,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "amenity/fuel/Coop": { - "tags": { - "name": "Coop", - "amenity": "fuel" - }, - "name": "Coop", - "icon": "fuel", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "operator", - "address", - "building_area" - ], - "suggestion": true - }, "amenity/fuel/Orlen": { "tags": { "name": "Orlen", @@ -72718,25 +73161,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "amenity/fuel/7-Eleven": { - "tags": { - "name": "7-Eleven", - "amenity": "fuel" - }, - "name": "7-Eleven", - "icon": "fuel", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "operator", - "address", - "building_area" - ], - "suggestion": true - }, "amenity/fuel/Agrola": { "tags": { "name": "Agrola", @@ -73858,25 +74282,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "amenity/fuel/Wawa": { - "tags": { - "name": "Wawa", - "amenity": "fuel" - }, - "name": "Wawa", - "icon": "fuel", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "operator", - "address", - "building_area" - ], - "suggestion": true - }, "amenity/fuel/Pertamina": { "tags": { "name": "Pertamina", @@ -74372,25 +74777,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "amenity/fuel/Circle K": { - "tags": { - "name": "Circle K", - "amenity": "fuel" - }, - "name": "Circle K", - "icon": "fuel", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "operator", - "address", - "building_area" - ], - "suggestion": true - }, "amenity/fuel/Posto Ipiranga": { "tags": { "name": "Posto Ipiranga", @@ -74543,25 +74929,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "amenity/fuel/Stewart's": { - "tags": { - "name": "Stewart's", - "amenity": "fuel" - }, - "name": "Stewart's", - "icon": "fuel", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "operator", - "address", - "building_area" - ], - "suggestion": true - }, "amenity/fuel/Posto BR": { "tags": { "name": "Posto BR", @@ -74733,25 +75100,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "amenity/fuel/H-E-B": { - "tags": { - "name": "H-E-B", - "amenity": "fuel" - }, - "name": "H-E-B", - "icon": "fuel", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "operator", - "address", - "building_area" - ], - "suggestion": true - }, "amenity/fuel/Укрнафта": { "tags": { "name": "Укрнафта", @@ -75828,6 +76176,28 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "amenity/fast_food/Subway": { + "tags": { + "name": "Subway", + "cuisine": "sandwich", + "amenity": "fast_food" + }, + "name": "Subway", + "icon": "fast-food", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "cuisine", + "building_area", + "address", + "opening_hours", + "smoking" + ], + "suggestion": true + }, "amenity/fast_food/Burger King": { "tags": { "name": "Burger King", @@ -80535,6 +80905,26 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "amenity/bank/Raiffeisenbank": { + "tags": { + "name": "Raiffeisenbank", + "amenity": "bank" + }, + "name": "Raiffeisenbank", + "icon": "bank", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "atm", + "building_area", + "address", + "opening_hours" + ], + "suggestion": true + }, "amenity/bank/Yorkshire Bank": { "tags": { "name": "Yorkshire Bank", @@ -86254,26 +86644,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "amenity/pharmacy/Радуга": { - "tags": { - "name": "Радуга", - "amenity": "pharmacy" - }, - "name": "Радуга", - "icon": "pharmacy", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "operator", - "building_area", - "address", - "opening_hours" - ], - "suggestion": true - }, "amenity/pharmacy/サンドラッグ": { "tags": { "name": "サンドラッグ", @@ -87434,6 +87804,25 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/supermarket/Morrisons": { + "tags": { + "name": "Morrisons", + "shop": "supermarket" + }, + "name": "Morrisons", + "icon": "grocery", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "operator", + "building_area", + "address" + ], + "suggestion": true + }, "shop/supermarket/Interspar": { "tags": { "name": "Interspar", @@ -87472,6 +87861,25 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/supermarket/Sainsbury's": { + "tags": { + "name": "Sainsbury's", + "shop": "supermarket" + }, + "name": "Sainsbury's", + "icon": "grocery", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "operator", + "building_area", + "address" + ], + "suggestion": true + }, "shop/supermarket/Lidl": { "tags": { "name": "Lidl", @@ -87548,6 +87956,44 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/supermarket/Coop": { + "tags": { + "name": "Coop", + "shop": "supermarket" + }, + "name": "Coop", + "icon": "grocery", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "operator", + "building_area", + "address" + ], + "suggestion": true + }, + "shop/supermarket/Tesco": { + "tags": { + "name": "Tesco", + "shop": "supermarket" + }, + "name": "Tesco", + "icon": "grocery", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "operator", + "building_area", + "address" + ], + "suggestion": true + }, "shop/supermarket/Woolworths": { "tags": { "name": "Woolworths", @@ -87890,25 +88336,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "shop/supermarket/Tesco Express": { - "tags": { - "name": "Tesco Express", - "shop": "supermarket" - }, - "name": "Tesco Express", - "icon": "grocery", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "operator", - "building_area", - "address" - ], - "suggestion": true - }, "shop/supermarket/King Soopers": { "tags": { "name": "King Soopers", @@ -88023,6 +88450,25 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/supermarket/Carrefour": { + "tags": { + "name": "Carrefour", + "shop": "supermarket" + }, + "name": "Carrefour", + "icon": "grocery", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "operator", + "building_area", + "address" + ], + "suggestion": true + }, "shop/supermarket/Waitrose": { "tags": { "name": "Waitrose", @@ -88422,6 +88868,25 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/supermarket/Super U": { + "tags": { + "name": "Super U", + "shop": "supermarket" + }, + "name": "Super U", + "icon": "grocery", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "operator", + "building_area", + "address" + ], + "suggestion": true + }, "shop/supermarket/Metro": { "tags": { "name": "Metro", @@ -88650,25 +89115,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "shop/supermarket/COOP Jednota": { - "tags": { - "name": "COOP Jednota", - "shop": "supermarket" - }, - "name": "COOP Jednota", - "icon": "grocery", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "operator", - "building_area", - "address" - ], - "suggestion": true - }, "shop/supermarket/Rema 1000": { "tags": { "name": "Rema 1000", @@ -89296,6 +89742,25 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/supermarket/Auchan": { + "tags": { + "name": "Auchan", + "shop": "supermarket" + }, + "name": "Auchan", + "icon": "grocery", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "operator", + "building_area", + "address" + ], + "suggestion": true + }, "shop/supermarket/Mercadona": { "tags": { "name": "Mercadona", @@ -89448,25 +89913,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "shop/supermarket/Costcutter": { - "tags": { - "name": "Costcutter", - "shop": "supermarket" - }, - "name": "Costcutter", - "icon": "grocery", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "operator", - "building_area", - "address" - ], - "suggestion": true - }, "shop/supermarket/Maxi": { "tags": { "name": "Maxi", @@ -89524,6 +89970,25 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/supermarket/Intermarché": { + "tags": { + "name": "Intermarché", + "shop": "supermarket" + }, + "name": "Intermarché", + "icon": "grocery", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "operator", + "building_area", + "address" + ], + "suggestion": true + }, "shop/supermarket/Delhaize": { "tags": { "name": "Delhaize", @@ -89695,25 +90160,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "shop/supermarket/dm": { - "tags": { - "name": "dm", - "shop": "supermarket" - }, - "name": "dm", - "icon": "grocery", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "operator", - "building_area", - "address" - ], - "suggestion": true - }, "shop/supermarket/Kvickly": { "tags": { "name": "Kvickly", @@ -89961,25 +90407,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "shop/supermarket/Petit Casino": { - "tags": { - "name": "Petit Casino", - "shop": "supermarket" - }, - "name": "Petit Casino", - "icon": "grocery", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "operator", - "building_area", - "address" - ], - "suggestion": true - }, "shop/supermarket/Wasgau": { "tags": { "name": "Wasgau", @@ -90569,25 +90996,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "shop/supermarket/Fressnapf": { - "tags": { - "name": "Fressnapf", - "shop": "supermarket" - }, - "name": "Fressnapf", - "icon": "grocery", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "operator", - "building_area", - "address" - ], - "suggestion": true - }, "shop/supermarket/Coop Konsum": { "tags": { "name": "Coop Konsum", @@ -90835,25 +91243,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "shop/supermarket/Centra": { - "tags": { - "name": "Centra", - "shop": "supermarket" - }, - "name": "Centra", - "icon": "grocery", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "operator", - "building_area", - "address" - ], - "suggestion": true - }, "shop/supermarket/Квартал": { "tags": { "name": "Квартал", @@ -91443,12 +91832,12 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "shop/supermarket/Атак": { + "shop/supermarket/H-E-B": { "tags": { - "name": "Атак", + "name": "H-E-B", "shop": "supermarket" }, - "name": "Атак", + "name": "H-E-B", "icon": "grocery", "geometry": [ "point", @@ -91462,12 +91851,12 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "shop/supermarket/Полушка": { + "shop/supermarket/Атак": { "tags": { - "name": "Полушка", + "name": "Атак", "shop": "supermarket" }, - "name": "Полушка", + "name": "Атак", "icon": "grocery", "geometry": [ "point", @@ -91481,12 +91870,12 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "shop/supermarket/Extra": { + "shop/supermarket/Полушка": { "tags": { - "name": "Extra", + "name": "Полушка", "shop": "supermarket" }, - "name": "Extra", + "name": "Полушка", "icon": "grocery", "geometry": [ "point", @@ -91500,12 +91889,12 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "shop/supermarket/Lewiatan": { + "shop/supermarket/Extra": { "tags": { - "name": "Lewiatan", + "name": "Extra", "shop": "supermarket" }, - "name": "Lewiatan", + "name": "Extra", "icon": "grocery", "geometry": [ "point", @@ -91557,25 +91946,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "shop/supermarket/Społem": { - "tags": { - "name": "Społem", - "shop": "supermarket" - }, - "name": "Społem", - "icon": "grocery", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "operator", - "building_area", - "address" - ], - "suggestion": true - }, "shop/supermarket/Bodega Aurrera": { "tags": { "name": "Bodega Aurrera", @@ -91652,25 +92022,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "shop/supermarket/Магазин": { - "tags": { - "name": "Магазин", - "shop": "supermarket" - }, - "name": "Магазин", - "icon": "grocery", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "operator", - "building_area", - "address" - ], - "suggestion": true - }, "shop/supermarket/Монетка": { "tags": { "name": "Монетка", @@ -92108,6 +92459,25 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/convenience/Tesco Express": { + "tags": { + "name": "Tesco Express", + "shop": "convenience" + }, + "name": "Tesco Express", + "icon": "shop", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "address", + "building_area", + "opening_hours" + ], + "suggestion": true + }, "shop/convenience/One Stop": { "tags": { "name": "One Stop", @@ -92146,6 +92516,25 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/convenience/7-Eleven": { + "tags": { + "name": "7-Eleven", + "shop": "convenience" + }, + "name": "7-Eleven", + "icon": "shop", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "address", + "building_area", + "opening_hours" + ], + "suggestion": true + }, "shop/convenience/Sale": { "tags": { "name": "Sale", @@ -92184,6 +92573,25 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/convenience/COOP Jednota": { + "tags": { + "name": "COOP Jednota", + "shop": "convenience" + }, + "name": "COOP Jednota", + "icon": "shop", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "address", + "building_area", + "opening_hours" + ], + "suggestion": true + }, "shop/convenience/Mac's": { "tags": { "name": "Mac's", @@ -92260,6 +92668,25 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/convenience/Costcutter": { + "tags": { + "name": "Costcutter", + "shop": "convenience" + }, + "name": "Costcutter", + "icon": "shop", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "address", + "building_area", + "opening_hours" + ], + "suggestion": true + }, "shop/convenience/Valintatalo": { "tags": { "name": "Valintatalo", @@ -92279,6 +92706,25 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/convenience/Circle K": { + "tags": { + "name": "Circle K", + "shop": "convenience" + }, + "name": "Circle K", + "icon": "shop", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "address", + "building_area", + "opening_hours" + ], + "suggestion": true + }, "shop/convenience/セブンイレブン": { "tags": { "name": "セブンイレブン", @@ -92319,6 +92765,25 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/convenience/Petit Casino": { + "tags": { + "name": "Petit Casino", + "shop": "convenience" + }, + "name": "Petit Casino", + "icon": "shop", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "address", + "building_area", + "opening_hours" + ], + "suggestion": true + }, "shop/convenience/Mace": { "tags": { "name": "Mace", @@ -92528,6 +92993,25 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/convenience/ABC": { + "tags": { + "name": "ABC", + "shop": "convenience" + }, + "name": "ABC", + "icon": "shop", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "address", + "building_area", + "opening_hours" + ], + "suggestion": true + }, "shop/convenience/ミニストップ": { "tags": { "name": "ミニストップ", @@ -92759,6 +93243,25 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/convenience/Магазин": { + "tags": { + "name": "Магазин", + "shop": "convenience" + }, + "name": "Магазин", + "icon": "shop", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "address", + "building_area", + "opening_hours" + ], + "suggestion": true + }, "shop/convenience/Гастроном": { "tags": { "name": "Гастроном", @@ -92797,6 +93300,25 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/convenience/Centra": { + "tags": { + "name": "Centra", + "shop": "convenience" + }, + "name": "Centra", + "icon": "shop", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "address", + "building_area", + "opening_hours" + ], + "suggestion": true + }, "shop/convenience/サークルK": { "tags": { "name": "サークルK", @@ -92817,6 +93339,25 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/convenience/Wawa": { + "tags": { + "name": "Wawa", + "shop": "convenience" + }, + "name": "Wawa", + "icon": "shop", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "address", + "building_area", + "opening_hours" + ], + "suggestion": true + }, "shop/convenience/Proxi": { "tags": { "name": "Proxi", @@ -92988,6 +93529,25 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/convenience/Społem": { + "tags": { + "name": "Społem", + "shop": "convenience" + }, + "name": "Społem", + "icon": "shop", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "address", + "building_area", + "opening_hours" + ], + "suggestion": true + }, "shop/convenience/Cumberland Farms": { "tags": { "name": "Cumberland Farms", @@ -93026,6 +93586,25 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/convenience/Kiosk": { + "tags": { + "name": "Kiosk", + "shop": "convenience" + }, + "name": "Kiosk", + "icon": "shop", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "address", + "building_area", + "opening_hours" + ], + "suggestion": true + }, "shop/convenience/24 часа": { "tags": { "name": "24 часа", @@ -93121,6 +93700,25 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/convenience/Stewart's": { + "tags": { + "name": "Stewart's", + "shop": "convenience" + }, + "name": "Stewart's", + "icon": "shop", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "address", + "building_area", + "opening_hours" + ], + "suggestion": true + }, "shop/convenience/Продукти": { "tags": { "name": "Продукти", @@ -93159,6 +93757,25 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/convenience/Радуга": { + "tags": { + "name": "Радуга", + "shop": "convenience" + }, + "name": "Радуга", + "icon": "shop", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "address", + "building_area", + "opening_hours" + ], + "suggestion": true + }, "shop/convenience/ローソンストア100": { "tags": { "name": "ローソンストア100", @@ -93539,6 +94156,25 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/convenience/Lewiatan": { + "tags": { + "name": "Lewiatan", + "shop": "convenience" + }, + "name": "Lewiatan", + "icon": "shop", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "address", + "building_area", + "opening_hours" + ], + "suggestion": true + }, "shop/convenience/Продуктовый магазин": { "tags": { "name": "Продуктовый магазин", @@ -93767,6 +94403,25 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/convenience/Boutique": { + "tags": { + "name": "Boutique", + "shop": "convenience" + }, + "name": "Boutique", + "icon": "shop", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "address", + "building_area", + "opening_hours" + ], + "suggestion": true + }, "shop/convenience/მარკეტი (Market)": { "tags": { "name": "მარკეტი (Market)", @@ -93805,6 +94460,25 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/chemist/dm": { + "tags": { + "name": "dm", + "shop": "chemist" + }, + "name": "dm", + "icon": "chemist", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "address", + "building_area", + "opening_hours" + ], + "suggestion": true + }, "shop/chemist/Müller": { "tags": { "name": "Müller", @@ -93976,25 +94650,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "shop/car_repair/Peugeot": { - "tags": { - "name": "Peugeot", - "shop": "car_repair" - }, - "name": "Peugeot", - "icon": "car", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "address", - "building_area", - "opening_hours" - ], - "suggestion": true - }, "shop/car_repair/Kwik Fit": { "tags": { "name": "Kwik Fit", @@ -94128,44 +94783,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "shop/car_repair/Автозапчасти": { - "tags": { - "name": "Автозапчасти", - "shop": "car_repair" - }, - "name": "Автозапчасти", - "icon": "car", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "address", - "building_area", - "opening_hours" - ], - "suggestion": true - }, - "shop/car_repair/Renault": { - "tags": { - "name": "Renault", - "shop": "car_repair" - }, - "name": "Renault", - "icon": "car", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "address", - "building_area", - "opening_hours" - ], - "suggestion": true - }, "shop/car_repair/Pit Stop": { "tags": { "name": "Pit Stop", @@ -94299,25 +94916,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "shop/car_repair/Citroen": { - "tags": { - "name": "Citroen", - "shop": "car_repair" - }, - "name": "Citroen", - "icon": "car", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "address", - "building_area", - "opening_hours" - ], - "suggestion": true - }, "shop/car_repair/Euromaster": { "tags": { "name": "Euromaster", @@ -94926,6 +95524,25 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/doityourself/Canadian Tire": { + "tags": { + "name": "Canadian Tire", + "shop": "doityourself" + }, + "name": "Canadian Tire", + "icon": "shop", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "address", + "building_area", + "opening_hours" + ], + "suggestion": true + }, "shop/doityourself/Leroy Merlin": { "tags": { "name": "Leroy Merlin", @@ -95154,25 +95771,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "shop/doityourself/Хозтовары": { - "tags": { - "name": "Хозтовары", - "shop": "doityourself" - }, - "name": "Хозтовары", - "icon": "shop", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "address", - "building_area", - "opening_hours" - ], - "suggestion": true - }, "shop/doityourself/Стройматериалы": { "tags": { "name": "Стройматериалы", @@ -95342,6 +95940,42 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/car/Citroen": { + "tags": { + "name": "Citroen", + "shop": "car" + }, + "name": "Citroen", + "icon": "car", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "address", + "opening_hours" + ], + "suggestion": true + }, + "shop/car/Renault": { + "tags": { + "name": "Renault", + "shop": "car" + }, + "name": "Renault", + "icon": "car", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "address", + "opening_hours" + ], + "suggestion": true + }, "shop/car/Mercedes-Benz": { "tags": { "name": "Mercedes-Benz", @@ -95378,6 +96012,24 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/car/Ford": { + "tags": { + "name": "Ford", + "shop": "car" + }, + "name": "Ford", + "icon": "car", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "address", + "opening_hours" + ], + "suggestion": true + }, "shop/car/Volkswagen": { "tags": { "name": "Volkswagen", @@ -95450,6 +96102,24 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/car/Автозапчасти": { + "tags": { + "name": "Автозапчасти", + "shop": "car" + }, + "name": "Автозапчасти", + "icon": "car", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "address", + "opening_hours" + ], + "suggestion": true + }, "shop/car/Opel": { "tags": { "name": "Opel", @@ -95558,6 +96228,24 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/car/Peugeot": { + "tags": { + "name": "Peugeot", + "shop": "car" + }, + "name": "Peugeot", + "icon": "car", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "address", + "opening_hours" + ], + "suggestion": true + }, "shop/car/Hyundai": { "tags": { "name": "Hyundai", @@ -96105,25 +96793,6 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, - "shop/clothes/Deichmann": { - "tags": { - "name": "Deichmann", - "shop": "clothes" - }, - "name": "Deichmann", - "icon": "clothing-store", - "geometry": [ - "point", - "vertex", - "area" - ], - "fields": [ - "address", - "building_area", - "opening_hours" - ], - "suggestion": true - }, "shop/clothes/Lindex": { "tags": { "name": "Lindex", @@ -98404,6 +99073,25 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/pet/Fressnapf": { + "tags": { + "name": "Fressnapf", + "shop": "pet" + }, + "name": "Fressnapf", + "icon": "dog-park", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "address", + "building_area", + "opening_hours" + ], + "suggestion": true + }, "shop/pet/PetSmart": { "tags": { "name": "PetSmart", @@ -98499,6 +99187,25 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/shoes/Deichmann": { + "tags": { + "name": "Deichmann", + "shop": "shoes" + }, + "name": "Deichmann", + "icon": "shop", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "address", + "building_area", + "opening_hours" + ], + "suggestion": true + }, "shop/shoes/Reno": { "tags": { "name": "Reno", @@ -99810,6 +100517,25 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "suggestion": true }, + "shop/hardware/Хозтовары": { + "tags": { + "name": "Хозтовары", + "shop": "hardware" + }, + "name": "Хозтовары", + "icon": "shop", + "geometry": [ + "point", + "vertex", + "area" + ], + "fields": [ + "address", + "building_area", + "opening_hours" + ], + "suggestion": true + }, "shop/motorcycle/Yamaha": { "tags": { "name": "Yamaha", @@ -99862,7 +100588,7 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," "point" ], "vertex": [ - "highway/crossing", + "highway/crosswalk", "railway/level_crossing", "highway/traffic_signals", "highway/turning_circle", @@ -99872,8 +100598,8 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," ], "relation": [ "category-route", + "category-restriction", "type/boundary", - "type/restriction", "type/multipolygon", "relation" ] @@ -99948,6 +100674,21 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," "railway/abandoned" ] }, + "category-restriction": { + "geometry": "relation", + "name": "Restriction", + "icon": "restriction", + "members": [ + "type/restriction/no_left_turn", + "type/restriction/no_right_turn", + "type/restriction/no_straight_on", + "type/restriction/no_u_turn", + "type/restriction/only_left_turn", + "type/restriction/only_right_turn", + "type/restriction/only_straight_on", + "type/restriction" + ] + }, "category-road": { "geometry": "line", "name": "Road", @@ -100336,6 +101077,11 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," "type": "typeCombo", "label": "Type" }, + "except": { + "key": "except", + "type": "combo", + "label": "Exceptions" + }, "fax": { "key": "fax", "type": "tel", @@ -100586,13 +101332,27 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," "oneway": { "key": "oneway", "type": "check", - "label": "One Way" + "label": "One Way", + "strings": { + "options": { + "undefined": "Assumed to be No", + "yes": "Yes", + "no": "No" + } + } }, "oneway_yes": { "key": "oneway", "type": "check", "default": "yes", - "label": "One Way" + "label": "One Way", + "strings": { + "options": { + "undefined": "Assumed to be Yes", + "yes": "Yes", + "no": "No" + } + } }, "opening_hours": { "key": "opening_hours", @@ -100732,6 +101492,15 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," "type": "combo", "label": "Type" }, + "restrictions": { + "type": "restrictions", + "geometry": "vertex", + "icon": "restrictions", + "reference": { + "rtype": "restriction" + }, + "label": "Turn Restrictions" + }, "route": { "key": "route", "type": "combo", @@ -112794,6 +113563,48 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," 920, 25 ] + }, + "restriction-no-straight-on": { + "relation": [ + 980, + 25 + ] + }, + "restriction-no-u-turn": { + "relation": [ + 1040, + 25 + ] + }, + "restriction-no-left-turn": { + "relation": [ + 1100, + 25 + ] + }, + "restriction-no-right-turn": { + "relation": [ + 1160, + 25 + ] + }, + "restriction-only-straight-on": { + "relation": [ + 1220, + 25 + ] + }, + "restriction-only-left-turn": { + "relation": [ + 1280, + 25 + ] + }, + "restriction-only-right-turn": { + "relation": [ + 1340, + 25 + ] } }, "operations": { @@ -112892,6 +113703,30 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," "icon-operation-disabled-continue": [ 220, 160 + ], + "icon-restriction-yes": [ + 50, + 80 + ], + "icon-restriction-no": [ + 95, + 80 + ], + "icon-restriction-only": [ + 140, + 80 + ], + "icon-restriction-yes-u": [ + 185, + 80 + ], + "icon-restriction-no-u": [ + 230, + 80 + ], + "icon-restriction-only-u": [ + 275, + 80 ] }, "locales": [ @@ -113140,6 +113975,18 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," }, "not_eligible": "Lines can't be split at their beginning or end.", "multiple_ways": "There are too many lines here to split." + }, + "restriction": { + "help": { + "select": "Click to select a road segment.", + "toggle": "Click to toggle turn restrictions.", + "toggle_on": "Click to add a \"{restriction}\" restriction.", + "toggle_off": "Click to remove the \"{restriction}\" restriction." + }, + "annotation": { + "create": "Added a turn restriction", + "delete": "Deleted a turn restriction" + } } }, "undo": { @@ -113374,6 +114221,9 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," "category-rail": { "name": "Rail" }, + "category-restriction": { + "name": "Restriction" + }, "category-road": { "name": "Road" }, @@ -113556,6 +114406,9 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," "entrance": { "label": "Type" }, + "except": { + "label": "Exceptions" + }, "fax": { "label": "Fax", "placeholder": "+31 42 123 4567" @@ -113701,10 +114554,20 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," "label": "Type" }, "oneway": { - "label": "One Way" + "label": "One Way", + "options": { + "undefined": "Assumed to be No", + "yes": "Yes", + "no": "No" + } }, "oneway_yes": { - "label": "One Way" + "label": "One Way", + "options": { + "undefined": "Assumed to be Yes", + "yes": "Yes", + "no": "No" + } }, "opening_hours": { "label": "Hours" @@ -113780,6 +114643,9 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," "restriction": { "label": "Type" }, + "restrictions": { + "label": "Turn Restrictions" + }, "route": { "label": "Type" }, @@ -114076,6 +114942,10 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," "name": "Doctor", "terms": "doctor,doctor's office" }, + "amenity/dojo": { + "name": "Dojo / Martial Arts Academy", + "terms": "martial arts,dojo,dojang" + }, "amenity/drinking_water": { "name": "Drinking Water", "terms": "water fountain,potable water" @@ -114662,6 +115532,10 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," }, "footway/crossing": { "name": "Crossing", + "terms": "" + }, + "footway/crosswalk": { + "name": "Crosswalk", "terms": "crosswalk,zebra crossing" }, "footway/sidewalk": { @@ -114718,6 +115592,10 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," }, "highway/crossing": { "name": "Crossing", + "terms": "" + }, + "highway/crosswalk": { + "name": "Crosswalk", "terms": "crosswalk,zebra crossing" }, "highway/cycleway": { @@ -114741,7 +115619,7 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," "terms": "" }, "highway/motorway_junction": { - "name": "Motorway Junction", + "name": "Motorway Junction / Exit", "terms": "" }, "highway/motorway_link": { @@ -115053,7 +115931,7 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," "terms": "" }, "leisure/sports_center": { - "name": "Sports Center", + "name": "Sports Center / Gym", "terms": "gym" }, "leisure/stadium": { @@ -115792,6 +116670,34 @@ iD.introGraph = '{"n185954700":{"id":"n185954700","loc":[-85.642244,41.939081]," "name": "Restriction", "terms": "" }, + "type/restriction/no_left_turn": { + "name": "No Left Turn", + "terms": "" + }, + "type/restriction/no_right_turn": { + "name": "No Right Turn", + "terms": "" + }, + "type/restriction/no_straight_on": { + "name": "No Straight On", + "terms": "" + }, + "type/restriction/no_u_turn": { + "name": "No U-turn", + "terms": "" + }, + "type/restriction/only_left_turn": { + "name": "Left Turn Only", + "terms": "" + }, + "type/restriction/only_right_turn": { + "name": "Right Turn Only", + "terms": "" + }, + "type/restriction/only_straight_on": { + "name": "No Turns", + "terms": "" + }, "type/route": { "name": "Route", "terms": ""