From a36c746b56a52323802d7ace2b1074741fba210b Mon Sep 17 00:00:00 2001 From: Tobias Zwick Date: Tue, 30 Apr 2019 23:26:20 +0200 Subject: [PATCH 01/12] Add bust, graffiti and installation artwork type preset --- .../presets/presets/tourism/artwork/bust.json | 22 ++++++++++++++++ .../presets/tourism/artwork/graffiti.json | 26 +++++++++++++++++++ .../presets/tourism/artwork/installation.json | 26 +++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 data/presets/presets/tourism/artwork/bust.json create mode 100644 data/presets/presets/tourism/artwork/graffiti.json create mode 100644 data/presets/presets/tourism/artwork/installation.json diff --git a/data/presets/presets/tourism/artwork/bust.json b/data/presets/presets/tourism/artwork/bust.json new file mode 100644 index 000000000..f6f02462e --- /dev/null +++ b/data/presets/presets/tourism/artwork/bust.json @@ -0,0 +1,22 @@ +{ + "icon": "maki-art-gallery", + "fields": [ + "name", + "artist", + "material" + ], + "geometry": [ + "point", "vertex" + ], + "tags": { + "tourism": "artwork", + "artwork_type": "bust" + }, + "reference": { + "key": "artwork_type" + }, + "terms": [ + "figure" + ], + "name": "Bust" +} diff --git a/data/presets/presets/tourism/artwork/graffiti.json b/data/presets/presets/tourism/artwork/graffiti.json new file mode 100644 index 000000000..ad813e01c --- /dev/null +++ b/data/presets/presets/tourism/artwork/graffiti.json @@ -0,0 +1,26 @@ +{ + "icon": "maki-art-gallery", + "fields": [ + "name", + "artist" + ], + "geometry": [ + "point", + "vertex", + "line", + "area" + ], + "tags": { + "tourism": "artwork", + "artwork_type": "graffiti" + }, + "reference": { + "key": "artwork_type" + }, + "terms": [ + "graffiti", + "Street Artwork", + "Guerilla Artwork" + ], + "name": "Graffiti Artwork" +} diff --git a/data/presets/presets/tourism/artwork/installation.json b/data/presets/presets/tourism/artwork/installation.json new file mode 100644 index 000000000..c8669bb20 --- /dev/null +++ b/data/presets/presets/tourism/artwork/installation.json @@ -0,0 +1,26 @@ +{ + "icon": "maki-art-gallery", + "fields": [ + "name", + "artist" + ], + "geometry": [ + "point", + "vertex", + "line", + "area" + ], + "tags": { + "tourism": "artwork", + "artwork_type": "installation" + }, + "reference": { + "key": "artwork_type" + }, + "terms": [ + "interactive art", + "intervention art", + "modern art" + ], + "name": "Installation Artwork" +} From 6a59a8c1f65a567d90e1a67aa64544633dcfd32b Mon Sep 17 00:00:00 2001 From: Tobias Zwick Date: Wed, 1 May 2019 00:09:36 +0200 Subject: [PATCH 02/12] change name to Installation Art --- data/presets/presets/tourism/artwork/installation.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/presets/presets/tourism/artwork/installation.json b/data/presets/presets/tourism/artwork/installation.json index c8669bb20..2824a3538 100644 --- a/data/presets/presets/tourism/artwork/installation.json +++ b/data/presets/presets/tourism/artwork/installation.json @@ -22,5 +22,5 @@ "intervention art", "modern art" ], - "name": "Installation Artwork" + "name": "Art Installation" } From d026f2f296c0c929aa7a84ea44f43a2dc5bccd16 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Tue, 30 Apr 2019 18:21:11 -0400 Subject: [PATCH 03/12] Add index property to tag rows, don't reorder on modifying key (closes #5927) --- modules/ui/raw_tag_editor.js | 63 ++++++++++++++---------------------- 1 file changed, 25 insertions(+), 38 deletions(-) diff --git a/modules/ui/raw_tag_editor.js b/modules/ui/raw_tag_editor.js index 7842b4089..3a3eae676 100644 --- a/modules/ui/raw_tag_editor.js +++ b/modules/ui/raw_tag_editor.js @@ -1,9 +1,5 @@ import { dispatch as d3_dispatch } from 'd3-dispatch'; - -import { - event as d3_event, - select as d3_select -} from 'd3-selection'; +import { event as d3_event, select as d3_select } from 'd3-selection'; import { t } from '../util/locale'; import { services } from '../services'; @@ -11,14 +7,14 @@ import { svgIcon } from '../svg/icon'; import { uiCombobox } from './combobox'; import { uiDisclosure } from './disclosure'; import { uiTagReference } from './tag_reference'; -import { utilGetSetValue, utilNoAuto, utilRebind } from '../util'; +import { utilArrayDifference, utilGetSetValue, utilNoAuto, utilRebind } from '../util'; export function uiRawTagEditor(context) { var taginfo = services.taginfo; var dispatch = d3_dispatch('change'); var _readOnlyTags = []; - var _orderedKeys = []; + var _indexedKeys = []; var _showBlank = false; var _updatePreference = true; var _expanded = false; @@ -56,34 +52,27 @@ export function uiRawTagEditor(context) { function content(wrap) { - var rowData = []; - var seen = {}; - var allKeys = Object.keys(_tags); - var i, k; - // When switching to a different entity or changing the state (hover/select) - // we reorder the keys. Otherwise leave them as the user entered - #5857 - if (!_orderedKeys.length) { - _orderedKeys = allKeys.sort(); + // reorder the keys alphabetically. + // We trigger this by emptying the `_indexedKeys` array, then it will be rebuilt here. + // Otherwise leave their order alone - #5857, #5927 + var all = Object.keys(_tags).sort(); + var known = _indexedKeys.map(function(t) { return t.key; }); + var missing = utilArrayDifference(all, known); + for (var i = 0; i < missing.length; i++) { + _indexedKeys.push({ index: _indexedKeys.length, key: missing[i] }); } - // push ordered keys first - for (i = 0; i < _orderedKeys.length; i++) { - k = _orderedKeys[i]; - if (_tags[k] === undefined) continue; // e.g. tag was removed - seen[k] = true; - rowData.push({ key: k, value: _tags[k] }); - } - // push unknown keys after - these are tags the user added - for (i = 0; i < allKeys.length; i++) { - k = allKeys[i]; - if (seen[k]) continue; - rowData.push({ key: k, value: _tags[k] }); - } - // push blank row last, if necessary - if (!rowData.length || _showBlank) { + // assemble row data, excluding any deleted tags + var rowData = _indexedKeys.map(function(row) { + var v = _tags[row.key]; + return (v === undefined) ? null : Object.assign(row, { value: v }); + }).filter(Boolean); + + // append blank row last, if necessary + if (!_indexedKeys.length || _showBlank) { _showBlank = false; - rowData.push({ key: '', value: '' }); + rowData.push({ index: _indexedKeys.length, key: '', value: '' }); } // List of tags @@ -170,7 +159,7 @@ export function uiRawTagEditor(context) { // Update items = items .merge(itemsEnter) - .order(); + .sort(function(a, b) { return a.index - b.index; }); items .each(function(d) { @@ -249,9 +238,7 @@ export function uiRawTagEditor(context) { query: value }, function(err, data) { if (!err) { - var filtered = data.filter(function(d) { - return _tags[d.value] === undefined; - }); + var filtered = data.filter(function(d) { return _tags[d.value] === undefined; }); callback(sort(value, filtered)); } }); @@ -355,7 +342,6 @@ export function uiRawTagEditor(context) { this.value = kNew; utilGetSetValue(inputVal, vNew); - scheduleChange(); } @@ -408,7 +394,7 @@ export function uiRawTagEditor(context) { rawTagEditor.state = function(val) { if (!arguments.length) return _state; if (_state !== val) { - _orderedKeys = []; + _indexedKeys = []; _state = val; } return rawTagEditor; @@ -439,7 +425,7 @@ export function uiRawTagEditor(context) { rawTagEditor.entityID = function(val) { if (!arguments.length) return _entityID; if (_entityID !== val) { - _orderedKeys = []; + _indexedKeys = []; _entityID = val; } return rawTagEditor; @@ -454,6 +440,7 @@ export function uiRawTagEditor(context) { }; + // pass an array of regular expressions to test against the tag key rawTagEditor.readOnlyTags = function(val) { if (!arguments.length) return _readOnlyTags; _readOnlyTags = val; From 250df5b6a84d98e3a24c891ccf075a7178f887c3 Mon Sep 17 00:00:00 2001 From: Tobias Zwick Date: Wed, 1 May 2019 11:12:44 +0200 Subject: [PATCH 04/12] use "Graffiti" instead of "Graffiti Artwork" as name --- data/presets/presets/tourism/artwork/graffiti.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data/presets/presets/tourism/artwork/graffiti.json b/data/presets/presets/tourism/artwork/graffiti.json index ad813e01c..bee56d6b1 100644 --- a/data/presets/presets/tourism/artwork/graffiti.json +++ b/data/presets/presets/tourism/artwork/graffiti.json @@ -18,9 +18,9 @@ "key": "artwork_type" }, "terms": [ - "graffiti", "Street Artwork", - "Guerilla Artwork" + "Guerilla Artwork", + "Graffiti Artwork" ], - "name": "Graffiti Artwork" + "name": "Graffiti" } From 1d8e27ef91ce210b44df87af631f5881ae9ab0b8 Mon Sep 17 00:00:00 2001 From: Quincy Morgan Date: Wed, 1 May 2019 09:06:40 -0700 Subject: [PATCH 05/12] Add derived data from prior merge --- data/presets.yaml | 15 +++++++++++++++ data/presets/presets.json | 3 +++ data/taginfo.json | 3 +++ dist/locales/en.json | 12 ++++++++++++ 4 files changed, 33 insertions(+) diff --git a/data/presets.yaml b/data/presets.yaml index 3263c85ec..64b2d4a73 100644 --- a/data/presets.yaml +++ b/data/presets.yaml @@ -7110,6 +7110,21 @@ en: name: Artwork # 'terms: mural,sculpture,statue' terms: '' + tourism/artwork/bust: + # 'tourism=artwork, artwork_type=bust' + name: Bust + # 'terms: figure' + terms: '' + tourism/artwork/graffiti: + # 'tourism=artwork, artwork_type=graffiti' + name: Graffiti + # 'terms: Street Artwork,Guerilla Artwork,Graffiti Artwork' + terms: '' + tourism/artwork/installation: + # 'tourism=artwork, artwork_type=installation' + name: Art Installation + # 'terms: interactive art,intervention art,modern art' + terms: '' tourism/artwork/mural: # 'tourism=artwork, artwork_type=mural' name: Mural diff --git a/data/presets/presets.json b/data/presets/presets.json index e3beba1af..73053af62 100644 --- a/data/presets/presets.json +++ b/data/presets/presets.json @@ -1066,6 +1066,9 @@ "tourism/apartment": {"icon": "maki-lodging", "fields": ["name", "operator", "address", "building_area", "rooms", "internet_access", "internet_access/fee"], "moreFields": ["building/levels_building", "height_building", "email", "fax", "internet_access/ssid", "payment_multi", "phone", "reservation", "smoking", "website", "wheelchair"], "geometry": ["point", "area"], "tags": {"tourism": "apartment"}, "name": "Guest Apartment / Condo"}, "tourism/aquarium": {"icon": "maki-aquarium", "fields": ["name", "operator", "address", "building_area", "opening_hours"], "moreFields": ["fee", "internet_access", "internet_access/fee", "internet_access/ssid", "payment_multi_fee", "smoking", "website", "phone", "email", "fax", "wheelchair"], "geometry": ["point", "area"], "terms": ["fish", "sea", "water"], "tags": {"tourism": "aquarium"}, "name": "Aquarium"}, "tourism/artwork": {"icon": "maki-art-gallery", "fields": ["name", "artwork_type", "artist"], "moreFields": ["material", "website"], "geometry": ["point", "vertex", "line", "area"], "tags": {"tourism": "artwork"}, "terms": ["mural", "sculpture", "statue"], "name": "Artwork"}, + "tourism/artwork/bust": {"icon": "maki-art-gallery", "fields": ["name", "artist", "material"], "geometry": ["point", "vertex"], "tags": {"tourism": "artwork", "artwork_type": "bust"}, "reference": {"key": "artwork_type"}, "terms": ["figure"], "name": "Bust"}, + "tourism/artwork/graffiti": {"icon": "maki-art-gallery", "fields": ["name", "artist"], "geometry": ["point", "vertex", "line", "area"], "tags": {"tourism": "artwork", "artwork_type": "graffiti"}, "reference": {"key": "artwork_type"}, "terms": ["Street Artwork", "Guerilla Artwork", "Graffiti Artwork"], "name": "Graffiti"}, + "tourism/artwork/installation": {"icon": "maki-art-gallery", "fields": ["name", "artist"], "geometry": ["point", "vertex", "line", "area"], "tags": {"tourism": "artwork", "artwork_type": "installation"}, "reference": {"key": "artwork_type"}, "terms": ["interactive art", "intervention art", "modern art"], "name": "Art Installation"}, "tourism/artwork/mural": {"icon": "maki-art-gallery", "fields": ["name", "artist"], "geometry": ["point", "vertex", "line", "area"], "tags": {"tourism": "artwork", "artwork_type": "mural"}, "reference": {"key": "artwork_type", "value": "mural"}, "terms": ["fresco", "wall painting"], "name": "Mural"}, "tourism/artwork/sculpture": {"icon": "maki-art-gallery", "fields": ["name", "artist", "material"], "geometry": ["point", "vertex", "line", "area"], "tags": {"tourism": "artwork", "artwork_type": "sculpture"}, "reference": {"key": "artwork_type", "value": "sculpture"}, "terms": ["statue", "figure", "carving"], "name": "Sculpture"}, "tourism/artwork/statue": {"icon": "maki-art-gallery", "fields": ["name", "artist", "material"], "geometry": ["point", "vertex", "line", "area"], "tags": {"tourism": "artwork", "artwork_type": "statue"}, "reference": {"key": "artwork_type", "value": "statue"}, "terms": ["sculpture", "figure", "carving"], "name": "Statue"}, diff --git a/data/taginfo.json b/data/taginfo.json index 513ee8ad6..3dd32a774 100644 --- a/data/taginfo.json +++ b/data/taginfo.json @@ -1003,6 +1003,9 @@ {"key": "tourism", "value": "apartment", "description": "🄿 Guest Apartment / Condo", "object_types": ["node", "area"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/lodging-15.svg?sanitize=true"}, {"key": "tourism", "value": "aquarium", "description": "🄿 Aquarium", "object_types": ["node", "area"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/aquarium-15.svg?sanitize=true"}, {"key": "tourism", "value": "artwork", "description": "🄿 Artwork", "object_types": ["node", "way", "area"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/art-gallery-15.svg?sanitize=true"}, + {"key": "artwork_type", "value": "bust", "description": "🄿 Bust", "object_types": ["node"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/art-gallery-15.svg?sanitize=true"}, + {"key": "artwork_type", "value": "graffiti", "description": "🄿 Graffiti", "object_types": ["node", "way", "area"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/art-gallery-15.svg?sanitize=true"}, + {"key": "artwork_type", "value": "installation", "description": "🄿 Art Installation", "object_types": ["node", "way", "area"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/art-gallery-15.svg?sanitize=true"}, {"key": "artwork_type", "value": "mural", "description": "🄿 Mural", "object_types": ["node", "way", "area"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/art-gallery-15.svg?sanitize=true"}, {"key": "artwork_type", "value": "sculpture", "description": "🄿 Sculpture", "object_types": ["node", "way", "area"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/art-gallery-15.svg?sanitize=true"}, {"key": "artwork_type", "value": "statue", "description": "🄿 Statue", "object_types": ["node", "way", "area"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/art-gallery-15.svg?sanitize=true"}, diff --git a/dist/locales/en.json b/dist/locales/en.json index 6f6e45291..6c33510a3 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -8498,6 +8498,18 @@ "name": "Artwork", "terms": "mural,sculpture,statue" }, + "tourism/artwork/bust": { + "name": "Bust", + "terms": "figure" + }, + "tourism/artwork/graffiti": { + "name": "Graffiti", + "terms": "Street Artwork,Guerilla Artwork,Graffiti Artwork" + }, + "tourism/artwork/installation": { + "name": "Art Installation", + "terms": "interactive art,intervention art,modern art" + }, "tourism/artwork/mural": { "name": "Mural", "terms": "fresco,wall painting" From 21dc6fe50061cb07773f6b0bd9ee0abeca075e89 Mon Sep 17 00:00:00 2001 From: Quincy Morgan Date: Wed, 1 May 2019 09:24:34 -0700 Subject: [PATCH 06/12] Update meadow preset terms (close #6280) --- data/presets.yaml | 1 + data/presets/presets.json | 2 +- data/presets/presets/landuse/meadow.json | 6 +++++- dist/locales/en.json | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/data/presets.yaml b/data/presets.yaml index 64b2d4a73..a3977487b 100644 --- a/data/presets.yaml +++ b/data/presets.yaml @@ -4685,6 +4685,7 @@ en: landuse/meadow: # landuse=meadow name: Meadow + # 'terms: grazing,hay field,pasture' terms: '' landuse/military: # landuse=military diff --git a/data/presets/presets.json b/data/presets/presets.json index 73053af62..6acfcc81a 100644 --- a/data/presets/presets.json +++ b/data/presets/presets.json @@ -547,7 +547,7 @@ "landuse/industrial/scrap_yard": {"icon": "maki-car", "fields": ["name", "operator", "address", "opening_hours"], "geometry": ["point", "area"], "tags": {"industrial": "scrap_yard"}, "addTags": {"landuse": "industrial", "industrial": "scrap_yard"}, "removeTags": {"landuse": "industrial", "industrial": "scrap_yard"}, "reference": {"key": "industrial", "value": "scrap_yard"}, "terms": ["car", "junk", "metal", "salvage", "scrap", "u-pull-it", "vehicle", "wreck", "yard"], "name": "Scrap Yard"}, "landuse/industrial/slaughterhouse": {"icon": "maki-slaughterhouse", "fields": ["name", "operator", "address", "building_area", "opening_hours"], "geometry": ["point", "area"], "tags": {"industrial": "slaughterhouse"}, "addTags": {"landuse": "industrial", "industrial": "slaughterhouse"}, "removeTags": {"landuse": "industrial", "industrial": "slaughterhouse"}, "reference": {"key": "industrial", "value": "slaughterhouse"}, "terms": ["abattoir", "beef", "butchery", "calf", "chicken", "cow", "killing house", "meat", "pig", "pork", "poultry", "shambles", "stockyard"], "name": "Slaughterhouse"}, "landuse/landfill": {"geometry": ["area"], "fields": ["name"], "moreFields": ["address", "website", "phone", "email", "fax"], "tags": {"landuse": "landfill"}, "terms": ["dump"], "name": "Landfill"}, - "landuse/meadow": {"icon": "maki-garden", "geometry": ["area"], "fields": ["name"], "tags": {"landuse": "meadow"}, "terms": [], "name": "Meadow"}, + "landuse/meadow": {"icon": "maki-garden", "geometry": ["area"], "fields": ["name"], "tags": {"landuse": "meadow"}, "terms": ["grazing", "hay field", "pasture"], "name": "Meadow"}, "landuse/military": {"icon": "temaki-military", "fields": ["name"], "moreFields": ["address", "website", "phone", "email", "fax"], "geometry": ["area"], "tags": {"landuse": "military"}, "terms": [], "matchScore": 0.9, "name": "Military Area"}, "landuse/military/airfield": {"icon": "tnp-2009265", "fields": ["name", "iata", "icao"], "geometry": ["point", "area"], "tags": {"military": "airfield"}, "addTags": {"aeroway": "aerodrome", "landuse": "military", "military": "airfield"}, "removeTags": {"aeroway": "aerodrome", "landuse": "military", "military": "airfield"}, "reference": {"key": "military", "value": "airfield"}, "terms": ["aerodrome", "aeroway", "air force", "airplane", "airport", "army", "base", "bomb", "fight", "force", "guard", "heli*", "jet", "marine", "navy", "plane", "troop", "war"], "name": "Military Airfield"}, "landuse/military/barracks": {"icon": "temaki-military", "fields": ["name", "building_area"], "geometry": ["point", "area"], "tags": {"military": "barracks"}, "addTags": {"landuse": "military", "military": "barracks"}, "removeTags": {"landuse": "military", "military": "barracks"}, "terms": ["air force", "army", "base", "fight", "force", "guard", "marine", "navy", "troop", "war"], "name": "Barracks"}, diff --git a/data/presets/presets/landuse/meadow.json b/data/presets/presets/landuse/meadow.json index b0185a4c9..44464136a 100644 --- a/data/presets/presets/landuse/meadow.json +++ b/data/presets/presets/landuse/meadow.json @@ -9,6 +9,10 @@ "tags": { "landuse": "meadow" }, - "terms": [], + "terms": [ + "grazing", + "hay field", + "pasture" + ], "name": "Meadow" } diff --git a/dist/locales/en.json b/dist/locales/en.json index 6c33510a3..68517896e 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -6424,7 +6424,7 @@ }, "landuse/meadow": { "name": "Meadow", - "terms": "" + "terms": "grazing,hay field,pasture" }, "landuse/military": { "name": "Military Area", From d3f767d6f4448ad338fdf2aa032432c6459124ec Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Wed, 1 May 2019 13:48:36 -0400 Subject: [PATCH 07/12] Code cleanups, prefix state variables with `_` --- modules/behavior/select.js | 75 ++++++++++++++++++++------------------ modules/modes/select.js | 48 ++++++++++++------------ 2 files changed, 63 insertions(+), 60 deletions(-) diff --git a/modules/behavior/select.js b/modules/behavior/select.js index f079a455c..50390c094 100644 --- a/modules/behavior/select.js +++ b/modules/behavior/select.js @@ -1,25 +1,21 @@ -import { - event as d3_event, - mouse as d3_mouse, - select as d3_select -} from 'd3-selection'; +import { event as d3_event, mouse as d3_mouse, select as d3_select } from 'd3-selection'; import { geoVecLength } from '../geo'; - import { modeBrowse } from '../modes/browse'; import { modeSelect } from '../modes/select'; import { modeSelectData } from '../modes/select_data'; import { modeSelectNote } from '../modes/select_note'; import { modeSelectError } from '../modes/select_error'; - import { osmEntity, osmNote, qaError } from '../osm'; export function behaviorSelect(context) { - var lastMouse = null; - var suppressMenu = true; + // legacy option to show menu on every click + var isShowAlways = +context.storage('edit-menu-show-always') === 1; var tolerance = 4; - var p1 = null; + var _lastMouse = null; + var _suppressMenu = true; + var _p1 = null; function point() { @@ -58,17 +54,20 @@ export function behaviorSelect(context) { function mousedown() { - if (!p1) p1 = point(); + if (!_p1) { + _p1 = point(); + } d3_select(window) .on('mouseup.select', mouseup, true); - var isShowAlways = +context.storage('edit-menu-show-always') === 1; - suppressMenu = !isShowAlways; + _suppressMenu = !isShowAlways; } function mousemove() { - if (d3_event) lastMouse = d3_event; + if (d3_event) { + _lastMouse = d3_event; + } } @@ -83,15 +82,17 @@ export function behaviorSelect(context) { e.stopPropagation(); if (!+e.clientX && !+e.clientY) { - if (lastMouse) { - e.sourceEvent = lastMouse; + if (_lastMouse) { + e.sourceEvent = _lastMouse; } else { return; } } - if (!p1) p1 = point(); - suppressMenu = false; + if (!_p1) { + _p1 = point(); + } + _suppressMenu = false; click(); } @@ -100,18 +101,20 @@ export function behaviorSelect(context) { d3_select(window) .on('mouseup.select', null, true); - if (!p1) return; + if (!_p1) return; var p2 = point(); - var dist = geoVecLength(p1, p2); + var dist = geoVecLength(_p1, p2); + _p1 = null; + if (dist > tolerance) return; - p1 = null; - if (dist > tolerance) { - return; - } + var e = d3_event; + processClick(e); // todo defer for 6028? + } - var isMultiselect = d3_event.shiftKey || d3_select('#surface .lasso').node(); - var isShowAlways = +context.storage('edit-menu-show-always') === 1; - var datum = d3_event.target.__data__ || (lastMouse && lastMouse.target.__data__); + + function processClick(e) { + var isMultiselect = e.shiftKey || d3_select('#surface .lasso').node(); + var datum = e.target.__data__ || (_lastMouse && _lastMouse.target.__data__); var mode = context.mode(); var entity = datum && datum.properties && datum.properties.entity; @@ -127,18 +130,18 @@ export function behaviorSelect(context) { context.selectedErrorID(null); if (!isMultiselect) { - if (selectedIDs.length > 1 && (!suppressMenu && !isShowAlways)) { + if (selectedIDs.length > 1 && (!_suppressMenu && !isShowAlways)) { // multiple things already selected, just show the menu... mode.suppressMenu(false).reselect(); } else { // select a single thing.. - context.enter(modeSelect(context, [datum.id]).suppressMenu(suppressMenu)); + context.enter(modeSelect(context, [datum.id]).suppressMenu(_suppressMenu)); } } else { if (selectedIDs.indexOf(datum.id) !== -1) { // clicked entity is already in the selectedIDs list.. - if (!suppressMenu && !isShowAlways) { + if (!_suppressMenu && !isShowAlways) { // don't deselect clicked entity, just show the menu. mode.suppressMenu(false).reselect(); } else { @@ -149,7 +152,7 @@ export function behaviorSelect(context) { } else { // clicked entity is not in the selected list, add it.. selectedIDs = selectedIDs.concat([datum.id]); - context.enter(modeSelect(context, selectedIDs).suppressMenu(suppressMenu)); + context.enter(modeSelect(context, selectedIDs).suppressMenu(_suppressMenu)); } } @@ -162,10 +165,12 @@ export function behaviorSelect(context) { context .selectedNoteID(datum.id) .enter(modeSelectNote(context, datum.id)); + } else if (datum instanceof qaError & !isMultiselect) { // clicked an external QA error context .selectedErrorID(datum.id) .enter(modeSelectError(context, datum.id, datum.service)); + } else { // clicked nothing.. context.selectedNoteID(null); context.selectedErrorID(null); @@ -175,14 +180,14 @@ export function behaviorSelect(context) { } // reset for next time.. - suppressMenu = true; + _suppressMenu = true; } function behavior(selection) { - lastMouse = null; - suppressMenu = true; - p1 = null; + _lastMouse = null; + _suppressMenu = true; + _p1 = null; d3_select(window) .on('keydown.select', keydown) diff --git a/modules/modes/select.js b/modules/modes/select.js index 0f614477f..17da72315 100644 --- a/modules/modes/select.js +++ b/modules/modes/select.js @@ -40,7 +40,6 @@ export function modeSelect(context, selectedIDs) { }; var keybinding = utilKeybinding('select'); - var timeout = null; var behaviors = [ behaviorCopy(context), behaviorPaste(context), @@ -51,11 +50,12 @@ export function modeSelect(context, selectedIDs) { modeDragNode(context).restoreSelectedIDs(selectedIDs).behavior, modeDragNote(context).behavior ]; - var inspector; + var inspector; // unused? var editMenu; - var newFeature = false; - var suppressMenu = true; - var follow = false; + var _timeout = null; + var _newFeature = false; + var _suppressMenu = true; + var _follow = false; var wrap = context.container() @@ -148,7 +148,7 @@ export function modeSelect(context, selectedIDs) { var entity = singular(); if (entity && context.geometry(entity.id) === 'relation') { - suppressMenu = true; + _suppressMenu = true; } else { var point = context.mouse(); var viewport = geoExtent(context.projection.clipExtent()).polygon(); @@ -156,7 +156,7 @@ export function modeSelect(context, selectedIDs) { if (point && geoPointInPolygon(point, viewport)) { editMenu.center(point); } else { - suppressMenu = true; + _suppressMenu = true; } } } @@ -203,29 +203,29 @@ export function modeSelect(context, selectedIDs) { } positionMenu(); - if (!suppressMenu) { + if (!_suppressMenu) { showMenu(); } }; mode.newFeature = function(val) { - if (!arguments.length) return newFeature; - newFeature = val; + if (!arguments.length) return _newFeature; + _newFeature = val; return mode; }; mode.suppressMenu = function(val) { - if (!arguments.length) return suppressMenu; - suppressMenu = val; + if (!arguments.length) return _suppressMenu; + _suppressMenu = val; return mode; }; mode.follow = function(val) { - if (!arguments.length) return follow; - follow = val; + if (!arguments.length) return _follow; + _follow = val; return mode; }; @@ -291,7 +291,7 @@ export function modeSelect(context, selectedIDs) { : uiEditMenu(context, operations); context.ui().sidebar - .select(singular() ? singular().id : null, newFeature); + .select(singular() ? singular().id : null, _newFeature); context.history() .on('undone.select', update) @@ -312,7 +312,7 @@ export function modeSelect(context, selectedIDs) { context.ui().sidebar.show(entities); } - if (follow) { + if (_follow) { var extent = geoExtent(); var graph = context.graph(); selectedIDs.forEach(function(id) { @@ -326,9 +326,9 @@ export function modeSelect(context, selectedIDs) { context.map().pan([0,0]); // full redraw, to adjust z-sorting #2914 } - timeout = window.setTimeout(function() { + _timeout = window.setTimeout(function() { positionMenu(); - if (!suppressMenu) { + if (!_suppressMenu) { showMenu(); } }, 270); /* after any centerEase completes */ @@ -378,7 +378,7 @@ export function modeSelect(context, selectedIDs) { var entity = singular(); if (entity && context.geometry(entity.id) === 'relation') { - suppressMenu = true; + _suppressMenu = true; return; } @@ -527,7 +527,7 @@ export function modeSelect(context, selectedIDs) { mode.exit = function() { - if (timeout) window.clearTimeout(timeout); + if (_timeout) window.clearTimeout(_timeout); if (inspector) wrap.call(inspector.close); behaviors.forEach(context.uninstall); @@ -560,16 +560,14 @@ export function modeSelect(context, selectedIDs) { context.features().forceVisible([]); var entity = singular(); - if (newFeature && - entity && - entity.type === 'relation' && + if (_newFeature && entity && entity.type === 'relation' && // no tags Object.keys(entity.tags).length === 0 && // no parent relations context.graph().parentRelations(entity).length === 0 && // no members or one member with no role - (entity.members.length === 0 || (entity.members.length === 1 && !entity.members[0].role))) { - + (entity.members.length === 0 || (entity.members.length === 1 && !entity.members[0].role)) + ) { // the user added this relation but didn't edit it at all, so just delete it var deleteAction = actionDeleteRelation(entity.id, true /* don't delete untagged members */); context.perform(deleteAction, t('operations.delete.annotation.relation')); From 907df1c10eb2ec0ce7cfa3f761caf71ccdd09d5e Mon Sep 17 00:00:00 2001 From: Quincy Morgan Date: Wed, 1 May 2019 11:08:52 -0700 Subject: [PATCH 08/12] Include relation members when forcing relations visible in all cases, not just selection (re: 6eeaf9407606bc06e87af735228d1a102a9ce254) --- modules/modes/select.js | 13 +------------ modules/renderer/features.js | 7 +++++++ 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/modules/modes/select.js b/modules/modes/select.js index 0f614477f..5af485984 100644 --- a/modules/modes/select.js +++ b/modules/modes/select.js @@ -233,18 +233,7 @@ export function modeSelect(context, selectedIDs) { mode.enter = function() { if (!checkSelectedIDs()) return; - var forceVisibleIDs = selectedIDs.slice(); - - selectedIDs.forEach(function(id) { - var entity = context.entity(id); - if (entity.type === 'relation') { - forceVisibleIDs = forceVisibleIDs.concat(entity.members.map(function(member) { - return member.id; - })); - } - }); - - context.features().forceVisible(forceVisibleIDs); + context.features().forceVisible(selectedIDs); var operations = Object.values(Operations) .map(function(o) { return o(selectedIDs, context); }) diff --git a/modules/renderer/features.js b/modules/renderer/features.js index 31aa32e40..281664471 100644 --- a/modules/renderer/features.js +++ b/modules/renderer/features.js @@ -511,6 +511,13 @@ export function rendererFeatures(context) { _forceVisible = {}; for (var i = 0; i < entityIDs.length; i++) { _forceVisible[entityIDs[i]] = true; + var entity = context.hasEntity(entityIDs[i]); + if (entity && entity.type === 'relation') { + // also show relation members (one level deep) + for (var j in entity.members) { + _forceVisible[entity.members[j].id] = true; + } + } } return features; }; From 949b57d11884b5930eaec0c72d95918d7b67ee37 Mon Sep 17 00:00:00 2001 From: Quincy Morgan Date: Wed, 1 May 2019 11:33:39 -0700 Subject: [PATCH 09/12] Ensure that relations are called before ways when categorizing fetched features (close #6277) --- modules/renderer/features.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/renderer/features.js b/modules/renderer/features.js index 281664471..ff4d26a3f 100644 --- a/modules/renderer/features.js +++ b/modules/renderer/features.js @@ -539,11 +539,14 @@ export function rendererFeatures(context) { // warm up the feature matching cache upon merging fetched data - context.history().on('merge.features', function(entities) { + context.history().on('merge.features', function(newEntities) { utilCallWhenIdle(function() { - if (!entities) return; + if (!newEntities) return; var graph = context.graph(); + var types = utilArrayGroupBy(newEntities, 'type'); + // ensure that getMatches is called on relations before ways + var entities = [].concat(types.relation || [], types.way || [], types.node || []); for (var i = 0; i < entities.length; i++) { var geometry = entities[i].geometry(graph); features.getMatches(entities[i], graph, geometry); From 37557a7c982699ee6c6958acb9966a76ebc73134 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Wed, 1 May 2019 14:47:29 -0400 Subject: [PATCH 10/12] Defer processing clicks in behaviorSelect (closes #6028) (I hope?) Because this click may trigger a blur event, and the blur event may trigger a tag change, and we really want that tag change to go to the already selected entity and not the one that we are about to select with the click #6028, #5878 (Be very careful entering modeSelect anywhere that might also blur a field!) --- modules/behavior/select.js | 17 ++++++++++----- test/spec/behavior/select.js | 42 +++++++++++++++++++++++++----------- 2 files changed, 42 insertions(+), 17 deletions(-) diff --git a/modules/behavior/select.js b/modules/behavior/select.js index 50390c094..311db7da0 100644 --- a/modules/behavior/select.js +++ b/modules/behavior/select.js @@ -107,14 +107,21 @@ export function behaviorSelect(context) { _p1 = null; if (dist > tolerance) return; - var e = d3_event; - processClick(e); // todo defer for 6028? + // Defer processing the click, + // because this click may trigger a blur event, + // and the blur event may trigger a tag change, + // and we really want that tag change to go to the already selected entity + // and not the one that we are about to select with the click #6028, #5878 + // (Be very careful entering modeSelect anywhere that might also blur a field!) + var datum = d3_event.target.__data__ || (_lastMouse && _lastMouse.target.__data__); + var isMultiselect = d3_event.shiftKey || d3_select('#surface .lasso').node(); + window.setTimeout(function() { + processClick(datum, isMultiselect); + }, 20); // delay > whatever raw_tag_editor.js `scheduleChange` does (10ms). } - function processClick(e) { - var isMultiselect = e.shiftKey || d3_select('#surface .lasso').node(); - var datum = e.target.__data__ || (_lastMouse && _lastMouse.target.__data__); + function processClick(datum, isMultiselect) { var mode = context.mode(); var entity = datum && datum.properties && datum.properties.entity; diff --git a/test/spec/behavior/select.js b/test/spec/behavior/select.js index 4994ca01b..ef42baa0e 100644 --- a/test/spec/behavior/select.js +++ b/test/spec/behavior/select.js @@ -43,50 +43,68 @@ describe('iD.behaviorSelect', function() { expect(context.mode().id).to.eql('browse'); }); - specify('click on entity selects the entity', function() { + specify('click on entity selects the entity', function(done) { var el = context.surface().selectAll('.' + a.id).node(); happen.mousedown(el); happen.mouseup(el); - expect(context.selectedIDs()).to.eql([a.id]); + window.setTimeout(function() { + expect(context.selectedIDs()).to.eql([a.id]); + done(); + }, 50); }); - specify('click on empty space clears the selection', function() { + specify('click on empty space clears the selection', function(done) { context.enter(iD.modeSelect(context, [a.id])); var el = context.surface().node(); happen.mousedown(el); happen.mouseup(el); - expect(context.mode().id).to.eql('browse'); + window.setTimeout(function() { + expect(context.mode().id).to.eql('browse'); + done(); + }, 50); }); - specify('shift-click on unselected entity adds it to the selection', function() { + specify('shift-click on unselected entity adds it to the selection', function(done) { context.enter(iD.modeSelect(context, [a.id])); var el = context.surface().selectAll('.' + b.id).node(); happen.mousedown(el, { shiftKey: true }); happen.mouseup(el, { shiftKey: true }); - expect(context.selectedIDs()).to.eql([a.id, b.id]); + window.setTimeout(function() { + expect(context.selectedIDs()).to.eql([a.id, b.id]); + done(); + }, 50); }); - specify('shift-click on selected entity removes it from the selection', function() { + specify('shift-click on selected entity removes it from the selection', function(done) { context.enter(iD.modeSelect(context, [a.id, b.id])); var el = context.surface().selectAll('.' + b.id).node(); happen.mousedown(el, { shiftKey: true }); happen.mouseup(el, { shiftKey: true }); - expect(context.selectedIDs()).to.eql([a.id]); + window.setTimeout(function() { + expect(context.selectedIDs()).to.eql([a.id]); + done(); + }, 50); }); - specify('shift-click on last selected entity clears the selection', function() { + specify('shift-click on last selected entity clears the selection', function(done) { context.enter(iD.modeSelect(context, [a.id])); var el = context.surface().selectAll('.' + a.id).node(); happen.mousedown(el, { shiftKey: true }); happen.mouseup(el, { shiftKey: true }); - expect(context.mode().id).to.eql('browse'); + window.setTimeout(function() { + expect(context.mode().id).to.eql('browse'); + done(); + }, 50); }); - specify('shift-click on empty space leaves the selection unchanged', function() { + specify('shift-click on empty space leaves the selection unchanged', function(done) { context.enter(iD.modeSelect(context, [a.id])); var el = context.surface().node(); happen.mousedown(el, { shiftKey: true }); happen.mouseup(el, { shiftKey: true }); - expect(context.selectedIDs()).to.eql([a.id]); + window.setTimeout(function() { + expect(context.selectedIDs()).to.eql([a.id]); + done(); + }, 50); }); }); From e93857012e40356d0b86bb3cf1756367b8ba40f8 Mon Sep 17 00:00:00 2001 From: Quincy Morgan Date: Wed, 1 May 2019 11:51:49 -0700 Subject: [PATCH 11/12] Add better icons for Bust and Statue presets --- data/presets/presets.json | 4 ++-- data/presets/presets/tourism/artwork/bust.json | 2 +- data/presets/presets/tourism/artwork/statue.json | 2 +- data/taginfo.json | 4 ++-- svg/fontawesome/fas-female.svg | 1 + svg/fontawesome/fas-user-alt.svg | 1 + 6 files changed, 8 insertions(+), 6 deletions(-) create mode 100644 svg/fontawesome/fas-female.svg create mode 100644 svg/fontawesome/fas-user-alt.svg diff --git a/data/presets/presets.json b/data/presets/presets.json index 6acfcc81a..1904b53eb 100644 --- a/data/presets/presets.json +++ b/data/presets/presets.json @@ -1066,12 +1066,12 @@ "tourism/apartment": {"icon": "maki-lodging", "fields": ["name", "operator", "address", "building_area", "rooms", "internet_access", "internet_access/fee"], "moreFields": ["building/levels_building", "height_building", "email", "fax", "internet_access/ssid", "payment_multi", "phone", "reservation", "smoking", "website", "wheelchair"], "geometry": ["point", "area"], "tags": {"tourism": "apartment"}, "name": "Guest Apartment / Condo"}, "tourism/aquarium": {"icon": "maki-aquarium", "fields": ["name", "operator", "address", "building_area", "opening_hours"], "moreFields": ["fee", "internet_access", "internet_access/fee", "internet_access/ssid", "payment_multi_fee", "smoking", "website", "phone", "email", "fax", "wheelchair"], "geometry": ["point", "area"], "terms": ["fish", "sea", "water"], "tags": {"tourism": "aquarium"}, "name": "Aquarium"}, "tourism/artwork": {"icon": "maki-art-gallery", "fields": ["name", "artwork_type", "artist"], "moreFields": ["material", "website"], "geometry": ["point", "vertex", "line", "area"], "tags": {"tourism": "artwork"}, "terms": ["mural", "sculpture", "statue"], "name": "Artwork"}, - "tourism/artwork/bust": {"icon": "maki-art-gallery", "fields": ["name", "artist", "material"], "geometry": ["point", "vertex"], "tags": {"tourism": "artwork", "artwork_type": "bust"}, "reference": {"key": "artwork_type"}, "terms": ["figure"], "name": "Bust"}, + "tourism/artwork/bust": {"icon": "fas-user-alt", "fields": ["name", "artist", "material"], "geometry": ["point", "vertex"], "tags": {"tourism": "artwork", "artwork_type": "bust"}, "reference": {"key": "artwork_type"}, "terms": ["figure"], "name": "Bust"}, "tourism/artwork/graffiti": {"icon": "maki-art-gallery", "fields": ["name", "artist"], "geometry": ["point", "vertex", "line", "area"], "tags": {"tourism": "artwork", "artwork_type": "graffiti"}, "reference": {"key": "artwork_type"}, "terms": ["Street Artwork", "Guerilla Artwork", "Graffiti Artwork"], "name": "Graffiti"}, "tourism/artwork/installation": {"icon": "maki-art-gallery", "fields": ["name", "artist"], "geometry": ["point", "vertex", "line", "area"], "tags": {"tourism": "artwork", "artwork_type": "installation"}, "reference": {"key": "artwork_type"}, "terms": ["interactive art", "intervention art", "modern art"], "name": "Art Installation"}, "tourism/artwork/mural": {"icon": "maki-art-gallery", "fields": ["name", "artist"], "geometry": ["point", "vertex", "line", "area"], "tags": {"tourism": "artwork", "artwork_type": "mural"}, "reference": {"key": "artwork_type", "value": "mural"}, "terms": ["fresco", "wall painting"], "name": "Mural"}, "tourism/artwork/sculpture": {"icon": "maki-art-gallery", "fields": ["name", "artist", "material"], "geometry": ["point", "vertex", "line", "area"], "tags": {"tourism": "artwork", "artwork_type": "sculpture"}, "reference": {"key": "artwork_type", "value": "sculpture"}, "terms": ["statue", "figure", "carving"], "name": "Sculpture"}, - "tourism/artwork/statue": {"icon": "maki-art-gallery", "fields": ["name", "artist", "material"], "geometry": ["point", "vertex", "line", "area"], "tags": {"tourism": "artwork", "artwork_type": "statue"}, "reference": {"key": "artwork_type", "value": "statue"}, "terms": ["sculpture", "figure", "carving"], "name": "Statue"}, + "tourism/artwork/statue": {"icon": "fas-female", "fields": ["name", "artist", "material"], "geometry": ["point", "vertex", "line", "area"], "tags": {"tourism": "artwork", "artwork_type": "statue"}, "reference": {"key": "artwork_type", "value": "statue"}, "terms": ["sculpture", "figure", "carving"], "name": "Statue"}, "tourism/attraction": {"icon": "maki-star", "fields": ["name", "operator", "address"], "geometry": ["point", "vertex", "line", "area"], "tags": {"tourism": "attraction"}, "matchScore": 0.75, "name": "Tourist Attraction"}, "tourism/camp_site": {"icon": "maki-campsite", "fields": ["name", "operator", "address", "access_simple", "capacity", "fee", "payment_multi_fee", "internet_access", "internet_access/fee"], "moreFields": ["email", "fax", "internet_access/ssid", "phone", "power_supply", "reservation", "sanitary_dump_station", "website", "wheelchair"], "geometry": ["point", "vertex", "area"], "terms": ["tent", "rv"], "tags": {"tourism": "camp_site"}, "name": "Campground"}, "tourism/caravan_site": {"icon": "temaki-rv_park", "fields": ["name", "address", "capacity", "sanitary_dump_station", "power_supply", "internet_access", "internet_access/fee"], "moreFields": ["operator", "fee", "payment_multi_fee", "internet_access/ssid", "smoking", "website", "phone", "email", "fax", "wheelchair", "reservation"], "geometry": ["point", "vertex", "area"], "terms": ["Motor Home", "Camper"], "tags": {"tourism": "caravan_site"}, "name": "RV Park"}, diff --git a/data/presets/presets/tourism/artwork/bust.json b/data/presets/presets/tourism/artwork/bust.json index f6f02462e..78c63c016 100644 --- a/data/presets/presets/tourism/artwork/bust.json +++ b/data/presets/presets/tourism/artwork/bust.json @@ -1,5 +1,5 @@ { - "icon": "maki-art-gallery", + "icon": "fas-user-alt", "fields": [ "name", "artist", diff --git a/data/presets/presets/tourism/artwork/statue.json b/data/presets/presets/tourism/artwork/statue.json index ed875c493..e81f198e2 100644 --- a/data/presets/presets/tourism/artwork/statue.json +++ b/data/presets/presets/tourism/artwork/statue.json @@ -1,5 +1,5 @@ { - "icon": "maki-art-gallery", + "icon": "fas-female", "fields": [ "name", "artist", diff --git a/data/taginfo.json b/data/taginfo.json index 3dd32a774..2bfba0998 100644 --- a/data/taginfo.json +++ b/data/taginfo.json @@ -1003,12 +1003,12 @@ {"key": "tourism", "value": "apartment", "description": "🄿 Guest Apartment / Condo", "object_types": ["node", "area"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/lodging-15.svg?sanitize=true"}, {"key": "tourism", "value": "aquarium", "description": "🄿 Aquarium", "object_types": ["node", "area"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/aquarium-15.svg?sanitize=true"}, {"key": "tourism", "value": "artwork", "description": "🄿 Artwork", "object_types": ["node", "way", "area"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/art-gallery-15.svg?sanitize=true"}, - {"key": "artwork_type", "value": "bust", "description": "🄿 Bust", "object_types": ["node"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/art-gallery-15.svg?sanitize=true"}, + {"key": "artwork_type", "value": "bust", "description": "🄿 Bust", "object_types": ["node"], "icon_url": "https://raw.githubusercontent.com/openstreetmap/iD/master/svg/fontawesome/fas-user-alt.svg?sanitize=true"}, {"key": "artwork_type", "value": "graffiti", "description": "🄿 Graffiti", "object_types": ["node", "way", "area"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/art-gallery-15.svg?sanitize=true"}, {"key": "artwork_type", "value": "installation", "description": "🄿 Art Installation", "object_types": ["node", "way", "area"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/art-gallery-15.svg?sanitize=true"}, {"key": "artwork_type", "value": "mural", "description": "🄿 Mural", "object_types": ["node", "way", "area"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/art-gallery-15.svg?sanitize=true"}, {"key": "artwork_type", "value": "sculpture", "description": "🄿 Sculpture", "object_types": ["node", "way", "area"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/art-gallery-15.svg?sanitize=true"}, - {"key": "artwork_type", "value": "statue", "description": "🄿 Statue", "object_types": ["node", "way", "area"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/art-gallery-15.svg?sanitize=true"}, + {"key": "artwork_type", "value": "statue", "description": "🄿 Statue", "object_types": ["node", "way", "area"], "icon_url": "https://raw.githubusercontent.com/openstreetmap/iD/master/svg/fontawesome/fas-female.svg?sanitize=true"}, {"key": "tourism", "value": "attraction", "description": "🄿 Tourist Attraction", "object_types": ["node", "way", "area"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/star-15.svg?sanitize=true"}, {"key": "tourism", "value": "camp_site", "description": "🄿 Campground", "object_types": ["node", "area"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/campsite-15.svg?sanitize=true"}, {"key": "tourism", "value": "caravan_site", "description": "🄿 RV Park", "object_types": ["node", "area"], "icon_url": "https://raw.githubusercontent.com/bhousel/temaki/master/icons/rv_park.svg?sanitize=true"}, diff --git a/svg/fontawesome/fas-female.svg b/svg/fontawesome/fas-female.svg new file mode 100644 index 000000000..2542a04cb --- /dev/null +++ b/svg/fontawesome/fas-female.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/svg/fontawesome/fas-user-alt.svg b/svg/fontawesome/fas-user-alt.svg new file mode 100644 index 000000000..3a344ef1b --- /dev/null +++ b/svg/fontawesome/fas-user-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file From d2cca04c3ffcdb4487fbfb92fd75ddce44e28cf5 Mon Sep 17 00:00:00 2001 From: Quincy Morgan Date: Wed, 1 May 2019 11:56:51 -0700 Subject: [PATCH 12/12] Deprecate artwork and artwork:type keys in favor of artwork_type --- data/deprecated.json | 8 ++++++++ data/taginfo.json | 2 ++ 2 files changed, 10 insertions(+) diff --git a/data/deprecated.json b/data/deprecated.json index af961b48f..d4eeb62fe 100644 --- a/data/deprecated.json +++ b/data/deprecated.json @@ -148,6 +148,14 @@ "old": {"amenity": "youth_centre"}, "replace": {"amenity": "community_centre", "community_centre:for": "juvenile"} }, + { + "old": {"artwork": "*"}, + "replace": {"artwork_type": "$1"} + }, + { + "old": {"artwork:type": "*"}, + "replace": {"artwork_type": "$1"} + }, { "old": {"barrier": "curb"}, "replace": {"barrier": "kerb"} diff --git a/data/taginfo.json b/data/taginfo.json index 2bfba0998..eaa689a18 100644 --- a/data/taginfo.json +++ b/data/taginfo.json @@ -1745,6 +1745,8 @@ {"key": "amenity", "value": "winery", "description": "🄳 ➜ craft=winery"}, {"key": "amenity", "value": "youth_center", "description": "🄳 ➜ amenity=community_centre + community_centre:for=juvenile"}, {"key": "amenity", "value": "youth_centre", "description": "🄳 ➜ amenity=community_centre + community_centre:for=juvenile"}, + {"key": "artwork", "description": "🄳 ➜ artwork_type=*"}, + {"key": "artwork:type", "description": "🄳 ➜ artwork_type=*"}, {"key": "barrier", "value": "curb", "description": "🄳 ➜ barrier=kerb"}, {"key": "barrier", "value": "embankment", "description": "🄳 ➜ man_made=embankment"}, {"key": "barrier", "value": "wire_fence", "description": "🄳 ➜ barrier=fence + fence_type=chain"},