From 949ed23e0a202c5af66e9b207896ca7c6a973c7c Mon Sep 17 00:00:00 2001 From: Wille Marcel Date: Fri, 8 Sep 2017 19:47:16 -0300 Subject: [PATCH 01/24] remove area from some presets geometry --- data/presets/presets.json | 12 ++++-------- .../presets/amenity/bicycle_repair_station.json | 3 +-- data/presets/presets/amenity/charging_station.json | 3 +-- data/presets/presets/amenity/waste_basket.json | 3 +-- data/presets/presets/highway/footway.json | 3 +-- 5 files changed, 8 insertions(+), 16 deletions(-) diff --git a/data/presets/presets.json b/data/presets/presets.json index 30e9fd2ec..ffc23476f 100644 --- a/data/presets/presets.json +++ b/data/presets/presets.json @@ -889,8 +889,7 @@ ], "geometry": [ "point", - "vertex", - "area" + "vertex" ], "terms": [ "bike", @@ -1088,8 +1087,7 @@ "capacity" ], "geometry": [ - "point", - "area" + "point" ], "tags": { "amenity": "charging_station" @@ -3200,8 +3198,7 @@ ], "geometry": [ "point", - "vertex", - "area" + "vertex" ], "tags": { "amenity": "waste_basket" @@ -6301,8 +6298,7 @@ "access" ], "geometry": [ - "line", - "area" + "line" ], "terms": [ "hike", diff --git a/data/presets/presets/amenity/bicycle_repair_station.json b/data/presets/presets/amenity/bicycle_repair_station.json index 717affe47..11dfd6d78 100644 --- a/data/presets/presets/amenity/bicycle_repair_station.json +++ b/data/presets/presets/amenity/bicycle_repair_station.json @@ -9,8 +9,7 @@ ], "geometry": [ "point", - "vertex", - "area" + "vertex" ], "terms": [ "bike", diff --git a/data/presets/presets/amenity/charging_station.json b/data/presets/presets/amenity/charging_station.json index 481fb0573..dfdb65ffe 100644 --- a/data/presets/presets/amenity/charging_station.json +++ b/data/presets/presets/amenity/charging_station.json @@ -5,8 +5,7 @@ "capacity" ], "geometry": [ - "point", - "area" + "point" ], "tags": { "amenity": "charging_station" diff --git a/data/presets/presets/amenity/waste_basket.json b/data/presets/presets/amenity/waste_basket.json index a3fa447f6..302c343a6 100644 --- a/data/presets/presets/amenity/waste_basket.json +++ b/data/presets/presets/amenity/waste_basket.json @@ -5,8 +5,7 @@ ], "geometry": [ "point", - "vertex", - "area" + "vertex" ], "tags": { "amenity": "waste_basket" diff --git a/data/presets/presets/highway/footway.json b/data/presets/presets/highway/footway.json index 613d00b7a..1e26b1d7f 100644 --- a/data/presets/presets/highway/footway.json +++ b/data/presets/presets/highway/footway.json @@ -9,8 +9,7 @@ "access" ], "geometry": [ - "line", - "area" + "line" ], "terms": [ "hike", From 6e2ad9deaf5b140f8fc912381d075aba1537cb78 Mon Sep 17 00:00:00 2001 From: Wille Marcel Date: Fri, 8 Sep 2017 19:59:00 -0300 Subject: [PATCH 02/24] add preset for vending=feminine_hygiene --- data/presets.yaml | 5 ++++ data/presets/presets.json | 23 +++++++++++++++++++ .../vending_machine/feminine_hygiene.json | 23 +++++++++++++++++++ data/taginfo.json | 4 ++++ dist/locales/en.json | 4 ++++ 5 files changed, 59 insertions(+) create mode 100644 data/presets/presets/amenity/vending_machine/feminine_hygiene.json diff --git a/data/presets.yaml b/data/presets.yaml index 515ee0ca5..9107eb177 100644 --- a/data/presets.yaml +++ b/data/presets.yaml @@ -2053,6 +2053,11 @@ en: name: Excrement Bag Vending Machine # 'terms: excrement bags,poop,dog,animal' terms: '' + amenity/vending_machine/feminine_hygiene: + # 'amenity=vending_machine, vending=feminine_hygiene' + name: Feminine Hygiene Vending Machine + # 'terms: condom, tampon, pad, woman, women, menstrual hygiene products, personal care' + terms: '' amenity/vending_machine/news_papers: # 'amenity=vending_machine, vending=news_papers' name: Newspaper Vending Machine diff --git a/data/presets/presets.json b/data/presets/presets.json index 30e9fd2ec..bce835bad 100644 --- a/data/presets/presets.json +++ b/data/presets/presets.json @@ -3039,6 +3039,29 @@ }, "name": "Excrement Bag Vending Machine" }, + "amenity/vending_machine/feminine_hygiene": { + "icon": "poi-vending-machine", + "fields": [ + "operator", + "payment_multi", + "currency_multi" + ], + "geometry": [ + "point" + ], + "terms": [ + "condom, tampon, pad, woman, women, menstrual hygiene products, personal care" + ], + "tags": { + "amenity": "vending_machine", + "vending": "feminine_hygiene" + }, + "reference": { + "key": "vending", + "value": "feminine_hygiene" + }, + "name": "Feminine Hygiene Vending Machine" + }, "amenity/vending_machine/newspapers": { "icon": "poi-vending-machine", "fields": [ diff --git a/data/presets/presets/amenity/vending_machine/feminine_hygiene.json b/data/presets/presets/amenity/vending_machine/feminine_hygiene.json new file mode 100644 index 000000000..fc3b4e9c4 --- /dev/null +++ b/data/presets/presets/amenity/vending_machine/feminine_hygiene.json @@ -0,0 +1,23 @@ +{ + "icon": "poi-vending-machine", + "fields": [ + "operator", + "payment_multi", + "currency_multi" + ], + "geometry": [ + "point" + ], + "terms": [ + "condom, tampon, pad, woman, women, menstrual hygiene products, personal care" + ], + "tags": { + "amenity": "vending_machine", + "vending": "feminine_hygiene" + }, + "reference": { + "key": "vending", + "value": "feminine_hygiene" + }, + "name": "Feminine Hygiene Vending Machine" +} diff --git a/data/taginfo.json b/data/taginfo.json index f62a1070c..9439b50de 100644 --- a/data/taginfo.json +++ b/data/taginfo.json @@ -555,6 +555,10 @@ "key": "vending", "value": "excrement_bags" }, + { + "key": "vending", + "value": "feminine_hygiene" + }, { "key": "vending", "value": "newspapers" diff --git a/dist/locales/en.json b/dist/locales/en.json index 12441b83f..26e9e321f 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -2845,6 +2845,10 @@ "name": "Excrement Bag Vending Machine", "terms": "excrement bags,poop,dog,animal" }, + "amenity/vending_machine/feminine_hygiene": { + "name": "Feminine Hygiene Vending Machine", + "terms": "condom, tampon, pad, woman, women, menstrual hygiene products, personal care" + }, "amenity/vending_machine/newspapers": { "name": "Newspaper Vending Machine", "terms": "newspaper" From 1c9719d7633c08f7b48240b03208d9dc6740f390 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Sat, 9 Sep 2017 08:51:13 -0400 Subject: [PATCH 03/24] Avoid requesting blank tiles from EsriWorldImagery (closes #4327) This allows the real tiles to overzoom, so the user does not see tiles with the "map data not yet available" message --- modules/renderer/background.js | 2 ++ modules/renderer/background_source.js | 50 +++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/modules/renderer/background.js b/modules/renderer/background.js index 5fc5286de..553047532 100644 --- a/modules/renderer/background.js +++ b/modules/renderer/background.js @@ -243,6 +243,8 @@ export function rendererBackground(context) { backgroundSources = dataImagery.map(function(source) { if (source.type === 'bing') { return rendererBackgroundSource.Bing(source, dispatch); + } else if (source.id === 'EsriWorldImagery') { + return rendererBackgroundSource.Esri(source); } else { return rendererBackgroundSource(source); } diff --git a/modules/renderer/background_source.js b/modules/renderer/background_source.js index de961de20..8cde7b1da 100644 --- a/modules/renderer/background_source.js +++ b/modules/renderer/background_source.js @@ -228,6 +228,56 @@ rendererBackgroundSource.Bing = function(data, dispatch) { }; + +rendererBackgroundSource.Esri = function(data) { + + // don't request blank tiles, instead overzoom real tiles - #4327 + if (data.template.match(/blankTile/) === null) { + data.template = data.template + '?blankTile=false'; + } + + var esri = rendererBackgroundSource(data), + cache = {}; + + esri.getVintage = function(center, tileCoord, callback) { + var tileId = tileCoord.slice(0, 3).join('/'); + // FIXME: construct service URL + // zoom = Math.min(tileCoord[2], esri.scaleExtent[1]), + // centerPoint = center[1] + ',' + center[0], // lat,lng + // url = 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial/' + centerPoint + + // '?zl=' + zoom + '&key=' + key + '&jsonp={callback}'; + + if (!cache[tileId]) { + cache[tileId] = {}; + } + if (cache[tileId] && cache[tileId].vintage) { + return callback(null, cache[tileId].vintage); + } + + // FIXME: remove dummy result: + callback(null, { start: null, end: null, range: '? - ?'}); + + // FIXME: call service instead: + // jsonpRequest(url, function(result) { + // var err = (!result && 'Unknown Error') || result.errorDetails; + // if (err) { + // return callback(err); + // } else { + // var vintage = { + // start: localeDateString(result.resourceSets[0].resources[0].vintageStart), + // end: localeDateString(result.resourceSets[0].resources[0].vintageEnd) + // }; + // vintage.range = vintageRange(vintage); + // cache[tileId].vintage = vintage; + // return callback(null, vintage); + // } + // }); + }; + + return esri; +}; + + rendererBackgroundSource.None = function() { var source = rendererBackgroundSource({ id: 'none', template: '' }); From 910c463d981eecd328fabe905392d343734530a2 Mon Sep 17 00:00:00 2001 From: Wille Marcel Date: Sat, 9 Sep 2017 12:18:22 -0300 Subject: [PATCH 04/24] add preset for hackerspace --- data/presets.yaml | 5 +++++ data/presets/presets.json | 20 +++++++++++++++++++ data/presets/presets/leisure/hackerspace.json | 20 +++++++++++++++++++ data/taginfo.json | 4 ++++ dist/locales/en.json | 4 ++++ 5 files changed, 53 insertions(+) create mode 100644 data/presets/presets/leisure/hackerspace.json diff --git a/data/presets.yaml b/data/presets.yaml index 9107eb177..52e474cf6 100644 --- a/data/presets.yaml +++ b/data/presets.yaml @@ -3256,6 +3256,11 @@ en: name: Golf Course # 'terms: links' terms: '' + leisure/hackerspace: + # leisure=hackerspace + name: Hackerspace + # 'terms: makerspace,hackspace,hacklab' + terms: '' leisure/horse_riding: # leisure=horse_riding name: Horseback Riding Facility diff --git a/data/presets/presets.json b/data/presets/presets.json index 69400532e..393638f45 100644 --- a/data/presets/presets.json +++ b/data/presets/presets.json @@ -8456,6 +8456,26 @@ }, "name": "Golf Course" }, + "leisure/hackerspace": { + "icon": "commercial", + "fields": [ + "name", + "address", + "website" + ], + "geometry": [ + "point" + ], + "terms": [ + "makerspace", + "hackspace", + "hacklab" + ], + "tags": { + "leisure": "hackerspace" + }, + "name": "Hackerspace" + }, "leisure/horse_riding": { "icon": "horse-riding", "fields": [ diff --git a/data/presets/presets/leisure/hackerspace.json b/data/presets/presets/leisure/hackerspace.json new file mode 100644 index 000000000..955b9f178 --- /dev/null +++ b/data/presets/presets/leisure/hackerspace.json @@ -0,0 +1,20 @@ +{ + "icon": "commercial", + "fields": [ + "name", + "address", + "website" + ], + "geometry": [ + "point" + ], + "terms": [ + "makerspace", + "hackspace", + "hacklab" + ], + "tags": { + "leisure": "hackerspace" + }, + "name": "Hackerspace" +} diff --git a/data/taginfo.json b/data/taginfo.json index 9439b50de..01c8c176c 100644 --- a/data/taginfo.json +++ b/data/taginfo.json @@ -1638,6 +1638,10 @@ "key": "leisure", "value": "golf_course" }, + { + "key": "leisure", + "value": "hackerspace" + }, { "key": "leisure", "value": "horse_riding" diff --git a/dist/locales/en.json b/dist/locales/en.json index 26e9e321f..7ceafa200 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -3937,6 +3937,10 @@ "name": "Golf Course", "terms": "links" }, + "leisure/hackerspace": { + "name": "Hackerspace", + "terms": "makerspace,hackspace,hacklab" + }, "leisure/horse_riding": { "name": "Horseback Riding Facility", "terms": "equestrian,stable" From f2de9383e1498a67b6a29c58e2606174ac6eb7ef Mon Sep 17 00:00:00 2001 From: Wille Marcel Date: Sat, 9 Sep 2017 12:24:08 -0300 Subject: [PATCH 05/24] fix feminine_hygiene terms --- data/presets.yaml | 2 +- data/presets/presets.json | 8 +++++++- .../presets/amenity/vending_machine/feminine_hygiene.json | 8 +++++++- dist/locales/en.json | 2 +- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/data/presets.yaml b/data/presets.yaml index 9107eb177..259ae9621 100644 --- a/data/presets.yaml +++ b/data/presets.yaml @@ -2056,7 +2056,7 @@ en: amenity/vending_machine/feminine_hygiene: # 'amenity=vending_machine, vending=feminine_hygiene' name: Feminine Hygiene Vending Machine - # 'terms: condom, tampon, pad, woman, women, menstrual hygiene products, personal care' + # 'terms: condom,tampon,pad,woman,women,menstrual hygiene products,personal care' terms: '' amenity/vending_machine/news_papers: # 'amenity=vending_machine, vending=news_papers' diff --git a/data/presets/presets.json b/data/presets/presets.json index 69400532e..f8ca562c3 100644 --- a/data/presets/presets.json +++ b/data/presets/presets.json @@ -3048,7 +3048,13 @@ "point" ], "terms": [ - "condom, tampon, pad, woman, women, menstrual hygiene products, personal care" + "condom", + "tampon", + "pad", + "woman", + "women", + "menstrual hygiene products", + "personal care" ], "tags": { "amenity": "vending_machine", diff --git a/data/presets/presets/amenity/vending_machine/feminine_hygiene.json b/data/presets/presets/amenity/vending_machine/feminine_hygiene.json index fc3b4e9c4..f76acb7b6 100644 --- a/data/presets/presets/amenity/vending_machine/feminine_hygiene.json +++ b/data/presets/presets/amenity/vending_machine/feminine_hygiene.json @@ -9,7 +9,13 @@ "point" ], "terms": [ - "condom, tampon, pad, woman, women, menstrual hygiene products, personal care" + "condom", + "tampon", + "pad", + "woman", + "women", + "menstrual hygiene products", + "personal care" ], "tags": { "amenity": "vending_machine", diff --git a/dist/locales/en.json b/dist/locales/en.json index 26e9e321f..1bc75b802 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -2847,7 +2847,7 @@ }, "amenity/vending_machine/feminine_hygiene": { "name": "Feminine Hygiene Vending Machine", - "terms": "condom, tampon, pad, woman, women, menstrual hygiene products, personal care" + "terms": "condom,tampon,pad,woman,women,menstrual hygiene products,personal care" }, "amenity/vending_machine/newspapers": { "name": "Newspaper Vending Machine", From 7521369ece0617054fefaa8ab66c716e98825394 Mon Sep 17 00:00:00 2001 From: jgravois Date: Sat, 9 Sep 2017 21:59:07 -0700 Subject: [PATCH 06/24] add support for displaying esri metadata --- data/core.yaml | 1 + modules/renderer/background_source.js | 64 +++++++++++++++++---------- modules/ui/panels/background.js | 16 ++++++- 3 files changed, 56 insertions(+), 25 deletions(-) diff --git a/data/core.yaml b/data/core.yaml index 902a4e78c..435a08fba 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -278,6 +278,7 @@ en: title: Background zoom: Zoom vintage: Vintage + source: Source unknown: Unknown show_tiles: Show Tiles hide_tiles: Hide Tiles diff --git a/modules/renderer/background_source.js b/modules/renderer/background_source.js index 8cde7b1da..6a4bcb2f1 100644 --- a/modules/renderer/background_source.js +++ b/modules/renderer/background_source.js @@ -232,6 +232,7 @@ rendererBackgroundSource.Bing = function(data, dispatch) { rendererBackgroundSource.Esri = function(data) { // don't request blank tiles, instead overzoom real tiles - #4327 + // deprecated technique, but it works (for now) if (data.template.match(/blankTile/) === null) { data.template = data.template + '?blankTile=false'; } @@ -240,12 +241,25 @@ rendererBackgroundSource.Esri = function(data) { cache = {}; esri.getVintage = function(center, tileCoord, callback) { - var tileId = tileCoord.slice(0, 3).join('/'); - // FIXME: construct service URL - // zoom = Math.min(tileCoord[2], esri.scaleExtent[1]), - // centerPoint = center[1] + ',' + center[0], // lat,lng - // url = 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial/' + centerPoint + - // '?zl=' + zoom + '&key=' + key + '&jsonp={callback}'; + var tileId = tileCoord.slice(0, 3).join('/'), + zoom = Math.min(tileCoord[2], esri.scaleExtent[1]), + centerPoint = center[0] + ',' + center[1], // long, lat (as it should be) + metadataLayer; + switch (true) { + case zoom >= 19: + metadataLayer = 3; + break; + case zoom >= 17: + metadataLayer = 2; + break; + case zoom >= 13: + metadataLayer = 0; + break; + default: + metadataLayer = 99; + } + // build up query using the layer appropriate to the current zoom + var url = 'https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/' + metadataLayer + '/query?returnGeometry=false&geometry=' + centerPoint + '&inSR=4326&geometryType=esriGeometryPoint&outFields=*&f=json&callback={callback}'; if (!cache[tileId]) { cache[tileId] = {}; @@ -254,24 +268,26 @@ rendererBackgroundSource.Esri = function(data) { return callback(null, cache[tileId].vintage); } - // FIXME: remove dummy result: - callback(null, { start: null, end: null, range: '? - ?'}); - - // FIXME: call service instead: - // jsonpRequest(url, function(result) { - // var err = (!result && 'Unknown Error') || result.errorDetails; - // if (err) { - // return callback(err); - // } else { - // var vintage = { - // start: localeDateString(result.resourceSets[0].resources[0].vintageStart), - // end: localeDateString(result.resourceSets[0].resources[0].vintageEnd) - // }; - // vintage.range = vintageRange(vintage); - // cache[tileId].vintage = vintage; - // return callback(null, vintage); - // } - // }); + // accurate metadata is only available at zoom 13 and closer + if (metadataLayer === 99) { + callback(null, { range: '', source: ' '}); + } else { + jsonpRequest(url, function(result) { + var err = !result || result.features.length < 1; + if (err) { + return callback(err); + } else { + var vintage = { + // pass through the discrete capture date from metadata + range: localeDateString(result.features[0].attributes.SRC_DATE2), + source: result.features[0].attributes.NICE_DESC + }; + + cache[tileId].vintage = vintage; + return callback(null, vintage); + } + }); + } }; return esri; diff --git a/modules/ui/panels/background.js b/modules/ui/panels/background.js index 44725af1b..9b5f6d303 100644 --- a/modules/ui/panels/background.js +++ b/modules/ui/panels/background.js @@ -8,7 +8,7 @@ export function uiPanelBackground(context) { var currSource = null; var currZoom = ''; var currVintage = ''; - + var currEsriSource = ''; function redraw(selection) { if (currSource !== background.baseLayerSource().name()) { @@ -45,6 +45,14 @@ export function uiPanelBackground(context) { debouncedGetVintage(selection); } + if (currSource === 'Esri World Imagery') { + list + .append('li') + .text(t('info_panels.background.source') + ': ') + .append('span') + .attr('class', 'source') + .text(currEsriSource); + } var toggle = context.getDebug('tile') ? 'hide_tiles' : 'show_tiles'; selection @@ -78,6 +86,12 @@ export function uiPanelBackground(context) { currVintage = (result && result.range) || t('info_panels.background.unknown'); selection.selectAll('.vintage') .text(currVintage); + // metadata from Esri can tell us the specific provider + if (result.source) { + currEsriSource = result.source; + selection.selectAll('.source') + .text(currEsriSource); + } }); } From 9c738cb5b719511142c51a6f99d11b88658dab19 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Sun, 10 Sep 2017 12:46:37 -0400 Subject: [PATCH 07/24] Restore preset ordering test with leading terms (regressed in af776501) The ordering did not actually change, but the test was failing because it was throwing away the preset terms.. preset.terms() actually returns translated terms not original terms, and should default to returning the original terms when translations are not available (like in testing). --- modules/presets/preset.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/presets/preset.js b/modules/presets/preset.js index a011e1b61..e9c2c6943 100644 --- a/modules/presets/preset.js +++ b/modules/presets/preset.js @@ -47,19 +47,19 @@ export function presetPreset(id, preset, fields) { }; - var name = preset.name || ''; + var origName = preset.name || ''; preset.name = function() { if (preset.suggestion) { id = id.split('/'); id = id[0] + '/' + id[1]; - return name + ' - ' + t('presets.presets.' + id + '.name'); + return origName + ' - ' + t('presets.presets.' + id + '.name'); } - return preset.t('name', {'default': name}); + return preset.t('name', { 'default': origName }); }; - + var origTerms = (preset.terms || []).join(); preset.terms = function() { - return preset.t('terms', {'default': ''}).toLowerCase().trim().split(/\s*,+\s*/); + return preset.t('terms', { 'default': origTerms }).toLowerCase().trim().split(/\s*,+\s*/); }; From 0d35c5ed595b3029287fb498c894438747a16172 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Sun, 10 Sep 2017 12:53:59 -0400 Subject: [PATCH 08/24] Give preset priority in preset list when search matches name exactly (closes #4325) --- modules/presets/collection.js | 14 ++++++++-- test/spec/presets/collection.js | 49 +++++++++++++++++++++++---------- 2 files changed, 46 insertions(+), 17 deletions(-) diff --git a/modules/presets/collection.js b/modules/presets/collection.js index 35e2b023b..e4b48939f 100644 --- a/modules/presets/collection.js +++ b/modules/presets/collection.js @@ -56,13 +56,23 @@ export function presetCollection(collection) { var leading_name = _.filter(searchable, function(a) { return leading(a.name().toLowerCase()); }).sort(function(a, b) { - var i; + var aCompare = a.name().toLowerCase(), + bCompare = b.name().toLowerCase(), + i; + + // priority if search string matches preset name exactly - #4325 + if (value === aCompare) return -1; + if (value === bCompare) return 1; + + // priority for higher matchScore i = b.originalScore - a.originalScore; if (i !== 0) return i; - i = a.name().toLowerCase().indexOf(value) - b.name().toLowerCase().indexOf(value); + // priority if search string appears earlier in preset name + i = aCompare.indexOf(value) - bCompare.indexOf(value); if (i !== 0) return i; + // priority for shorter preset names return a.name().length - b.name().length; }); diff --git a/test/spec/presets/collection.js b/test/spec/presets/collection.js index e88912329..45af5e4c3 100644 --- a/test/spec/presets/collection.js +++ b/test/spec/presets/collection.js @@ -49,7 +49,14 @@ describe('iD.presetCollection', function() { name: 'Park', tags: { leisure: 'park' }, geometry: ['point', 'area'], - terms: [ 'grass' ] + terms: [ 'grass' ], + matchScore: 0.5 + }), + parking: iD.presetPreset('__test/amenity/parking', { + name: 'Parking', + tags: { amenity: 'parking' }, + geometry: ['point', 'area'], + terms: [ 'cars' ] }), soccer: iD.presetPreset('__test/leisure/pitch/soccer', { name: 'Soccer Field', @@ -68,7 +75,7 @@ describe('iD.presetCollection', function() { var c = iD.presetCollection([ p.point, p.line, p.area, p.grill, p.sandpit, p.residential, - p.grass1, p.grass2, p.park, p.soccer, p.football + p.grass1, p.grass2, p.park, p.parking, p.soccer, p.football ]); describe('#item', function() { @@ -93,30 +100,42 @@ describe('iD.presetCollection', function() { it('returns alternate matches in correct order', function() { var col = c.search('gri', 'point').matchGeometry('point').collection; - expect(col.indexOf(p.grill)).to.eql(0); // 1. 'Grill' (leading name) - expect(col.indexOf(p.football)).to.eql(7); // 2. 'Football' (leading term 'gridiron') - expect(col.indexOf(p.sandpit)).to.eql(1); // 3. 'Sandpit' (leading tag value 'grit_bin') - expect(col.indexOf(p.grass1)).to.be.within(2,3); // 4. 'Grass' (similar name) - expect(col.indexOf(p.grass2)).to.be.within(3,4); // 5. 'Ğṝȁß' (similar name) - expect(col.indexOf(p.park)).to.eql(4); // 6. 'Park' (similar term 'grass') + expect(col.indexOf(p.grill), 'Grill').to.eql(0); // 1. 'Grill' (leading name) + expect(col.indexOf(p.football), 'Football').to.eql(1); // 2. 'Football' (leading term 'gridiron') + expect(col.indexOf(p.sandpit), 'Sandpit').to.eql(2); // 3. 'Sandpit' (leading tag value 'grit_bin') + expect(col.indexOf(p.grass1), 'Grass').to.be.within(3,4); // 4. 'Grass' (similar name) + expect(col.indexOf(p.grass2), 'Ğṝȁß').to.be.within(3,4); // 5. 'Ğṝȁß' (similar name) + expect(col.indexOf(p.park), 'Park').to.eql(5); // 6. 'Park' (similar term 'grass') + }); + + it('sorts preset with matchScore penalty below others', function() { + var col = c.search('par', 'point').matchGeometry('point').collection; + expect(col.indexOf(p.parking), 'Parking').to.eql(0); // 1. 'Parking' (default matchScore) + expect(col.indexOf(p.park), 'Park').to.eql(1); // 2. 'Park' (low matchScore) + }); + + it('ignores matchScore penalty for exact name match', function() { + var col = c.search('park', 'point').matchGeometry('point').collection; + expect(col.indexOf(p.park), 'Park').to.eql(0); // 1. 'Park' (low matchScore) + expect(col.indexOf(p.parking), 'Parking').to.eql(1); // 2. 'Parking' (default matchScore) }); it('considers diacritics on exact matches', function() { var col = c.search('ğṝȁ', 'point').matchGeometry('point').collection; - expect(col.indexOf(p.grass2)).to.eql(0); // 1. 'Ğṝȁß' (leading name) - expect(col.indexOf(p.grass1)).to.eql(1); // 2. 'Grass' (similar name) + expect(col.indexOf(p.grass2), 'Ğṝȁß').to.eql(0); // 1. 'Ğṝȁß' (leading name) + expect(col.indexOf(p.grass1), 'Grass').to.eql(1); // 2. 'Grass' (similar name) }); it('replaces diacritics on fuzzy matches', function() { var col = c.search('graß', 'point').matchGeometry('point').collection; - expect(col.indexOf(p.grass1)).to.be.within(0,1); // 1. 'Grass' (similar name) - expect(col.indexOf(p.grass2)).to.be.within(0,1); // 2. 'Ğṝȁß' (similar name) + expect(col.indexOf(p.grass1), 'Grass').to.be.within(0,1); // 1. 'Grass' (similar name) + expect(col.indexOf(p.grass2), 'Ğṝȁß').to.be.within(0,1); // 2. 'Ğṝȁß' (similar name) }); it('includes the appropriate fallback preset', function() { - expect(c.search('foo', 'point').collection).to.include(p.point); - expect(c.search('foo', 'line').collection).to.include(p.line); - expect(c.search('foo', 'area').collection).to.include(p.area); + expect(c.search('foo', 'point').collection, 'point').to.include(p.point); + expect(c.search('foo', 'line').collection, 'line').to.include(p.line); + expect(c.search('foo', 'area').collection, 'area').to.include(p.area); }); it('excludes presets with searchable: false', function() { From 9719a31c79844bfc4f39a791fcc687c70794898e Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Mon, 11 Sep 2017 09:55:29 -0400 Subject: [PATCH 09/24] Match less punctuation in hashtags (closes #4303) --- modules/ui/commit.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/ui/commit.js b/modules/ui/commit.js index 9582a8386..75248ea8f 100644 --- a/modules/ui/commit.js +++ b/modules/ui/commit.js @@ -283,7 +283,7 @@ export function uiCommit(context) { // Extract hashtags from `comment` function commentTags() { - return tags.comment.match(/#[^\s\#]+/g); + return tags.comment.match(/#[\w-]+/g); } // Extract and clean hashtags from `hashtags` @@ -293,7 +293,7 @@ export function uiCommit(context) { .split(/[,;\s]+/) .map(function (s) { if (s[0] !== '#') { s = '#' + s; } // prepend '#' - var matched = s.match(/#[^\s\#]+/g); // match valid hashtags + var matched = s.match(/#[\w-]+/g); // match valid hashtags return matched && matched[0]; }).filter(Boolean); // exclude falsey } From 5e6db23dc9e931f813cb165cd6303327c129c36e Mon Sep 17 00:00:00 2001 From: Wille Marcel Date: Mon, 11 Sep 2017 11:10:20 -0300 Subject: [PATCH 10/24] update hackerspace preset and add terms for bowling_alley --- data/presets.yaml | 1 + data/presets/presets.json | 9 +++++++-- data/presets/presets/leisure/bowling_alley.json | 1 + data/presets/presets/leisure/hackerspace.json | 5 ++++- dist/locales/en.json | 2 +- 5 files changed, 14 insertions(+), 4 deletions(-) diff --git a/data/presets.yaml b/data/presets.yaml index 52e474cf6..f614224da 100644 --- a/data/presets.yaml +++ b/data/presets.yaml @@ -3212,6 +3212,7 @@ en: leisure/bowling_alley: # leisure=bowling_alley name: Bowling Alley + # 'terms: bowling center' terms: '' leisure/common: # leisure=common diff --git a/data/presets/presets.json b/data/presets/presets.json index 393638f45..6938bb3a5 100644 --- a/data/presets/presets.json +++ b/data/presets/presets.json @@ -8271,7 +8271,9 @@ "point", "area" ], - "terms": [], + "terms": [ + "bowling center" + ], "tags": { "leisure": "bowling_alley" }, @@ -8461,10 +8463,13 @@ "fields": [ "name", "address", + "building_area", + "opening_hours", "website" ], "geometry": [ - "point" + "point", + "area" ], "terms": [ "makerspace", diff --git a/data/presets/presets/leisure/bowling_alley.json b/data/presets/presets/leisure/bowling_alley.json index 63ca737c2..ce6938a3a 100644 --- a/data/presets/presets/leisure/bowling_alley.json +++ b/data/presets/presets/leisure/bowling_alley.json @@ -13,6 +13,7 @@ "area" ], "terms": [ + "bowling center" ], "tags": { "leisure": "bowling_alley" diff --git a/data/presets/presets/leisure/hackerspace.json b/data/presets/presets/leisure/hackerspace.json index 955b9f178..fdffb2725 100644 --- a/data/presets/presets/leisure/hackerspace.json +++ b/data/presets/presets/leisure/hackerspace.json @@ -3,10 +3,13 @@ "fields": [ "name", "address", + "building_area", + "opening_hours", "website" ], "geometry": [ - "point" + "point", + "area" ], "terms": [ "makerspace", diff --git a/dist/locales/en.json b/dist/locales/en.json index 7ceafa200..aa97f502e 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -3899,7 +3899,7 @@ }, "leisure/bowling_alley": { "name": "Bowling Alley", - "terms": "" + "terms": "bowling center" }, "leisure/common": { "name": "Common", From ba8a1e6bc60e0b4f7bcf2b1d216a5defb100425d Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Mon, 11 Sep 2017 11:50:59 -0400 Subject: [PATCH 11/24] Several changes to avoid storing stale hashtags (closes #4304) - remove context.storage hashtags whenever hashtags are detected in comment. - when changing the comment, override hashtags with any found in comment. --- modules/ui/commit.js | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/modules/ui/commit.js b/modules/ui/commit.js index 75248ea8f..30b528bd5 100644 --- a/modules/ui/commit.js +++ b/modules/ui/commit.js @@ -40,29 +40,31 @@ export function uiCommit(context) { var osm = context.connection(); if (!osm) return; - var comment = context.storage('comment') || '', - commentDate = +context.storage('commentDate') || 0, - hashtags = context.storage('hashtags'), + // expire stored comment and hashtags after cutoff datetime - #3947 + var commentDate = +context.storage('commentDate') || 0, currDate = Date.now(), cutoff = 2 * 86400 * 1000; // 2 days - - // expire stored comment and hashtags after cutoff datetime - #3947 if (commentDate > currDate || currDate - commentDate > cutoff) { - comment = ''; - hashtags = undefined; + context.storage('comment', null); + context.storage('hashtags', null); } var tags; if (!changeset) { var detected = utilDetect(); tags = { - comment: comment, + comment: context.storage('comment') || '', created_by: ('iD ' + context.version).substr(0, 255), imagery_used: context.history().imageryUsed().join(';').substr(0, 255), host: detected.host.substr(0, 255), locale: detected.locale.substr(0, 255) }; + // call findHashtags initially - this will remove stored + // hashtags if any hashtags are found in the comment - #4304 + findHashtags(tags, true); + + var hashtags = context.storage('hashtags'); if (hashtags) { tags.hashtags = hashtags; } @@ -276,8 +278,15 @@ export function uiCommit(context) { } - function findHashtags(tags) { - return _.unionBy(commentTags(), hashTags(), function (s) { + function findHashtags(tags, commentOnly) { + var inComment = commentTags(), + inHashTags = hashTags(); + + if (inComment !== null) { // when hashtags are detected in comment... + context.storage('hashtags', null); // always remove stored hashtags - #4304 + if (commentOnly) { inHashTags = null; } // optionally override hashtags field + } + return _.unionBy(inComment, inHashTags, function (s) { return s.toLowerCase(); }); @@ -327,7 +336,9 @@ export function uiCommit(context) { }); if (!onInput) { - var arr = findHashtags(tags); + // when changing the comment, override hashtags with any found in comment. + var commentOnly = changed.hasOwnProperty('comment') && (changed.comment !== ''); + var arr = findHashtags(tags, commentOnly); if (arr.length) { tags.hashtags = arr.join(';').substr(0, 255); context.storage('hashtags', tags.hashtags); From 0f153d7d55bfa862a78b7f3bd64b948fdb1efc3b Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Mon, 11 Sep 2017 12:09:58 -0400 Subject: [PATCH 12/24] Ignore URLish fragments when detecting hashtags in changeset comment (closes #4289) --- modules/ui/commit.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/ui/commit.js b/modules/ui/commit.js index 30b528bd5..0492e3a37 100644 --- a/modules/ui/commit.js +++ b/modules/ui/commit.js @@ -292,7 +292,9 @@ export function uiCommit(context) { // Extract hashtags from `comment` function commentTags() { - return tags.comment.match(/#[\w-]+/g); + return tags.comment + .replace(/http\S*/g, '') // drop anything that looks like a URL - #4289 + .match(/#[\w-]+/g); } // Extract and clean hashtags from `hashtags` From 5f341366e7944091e15b6caa94e7fc434aeb82b2 Mon Sep 17 00:00:00 2001 From: john gravois Date: Mon, 11 Sep 2017 09:51:07 -0700 Subject: [PATCH 13/24] display additional metadata from Esri World Imagery * getVintage() becomes getMetadata() * ignore a couple unrelated lint nags * add source description, resolution and accuracy info to debug panel --- data/core.yaml | 3 ++ modules/renderer/background_source.js | 24 +++++++++---- modules/renderer/tile_layer.js | 2 +- modules/ui/panels/background.js | 49 ++++++++++++++++++++++----- modules/ui/status.js | 1 + test/spec/spec_helpers.js | 3 +- 6 files changed, 64 insertions(+), 18 deletions(-) diff --git a/data/core.yaml b/data/core.yaml index 435a08fba..82df21868 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -279,6 +279,9 @@ en: zoom: Zoom vintage: Vintage source: Source + description: Description + resolution: Resolution + accuracy: Accuracy unknown: Unknown show_tiles: Show Tiles hide_tiles: Hide Tiles diff --git a/modules/renderer/background_source.js b/modules/renderer/background_source.js index 6a4bcb2f1..1a0814f21 100644 --- a/modules/renderer/background_source.js +++ b/modules/renderer/background_source.js @@ -133,7 +133,7 @@ export function rendererBackgroundSource(data) { source.copyrightNotices = function() {}; - source.getVintage = function(center, tileCoord, callback) { + source.getMetadata = function(center, tileCoord, callback) { var vintage = { start: localeDateString(source.startDate), end: localeDateString(source.endDate) @@ -190,7 +190,7 @@ rendererBackgroundSource.Bing = function(data, dispatch) { }; - bing.getVintage = function(center, tileCoord, callback) { + bing.getMetadata = function(center, tileCoord, callback) { var tileId = tileCoord.slice(0, 3).join('/'), zoom = Math.min(tileCoord[2], 21), centerPoint = center[1] + ',' + center[0], // lat,lng @@ -240,7 +240,7 @@ rendererBackgroundSource.Esri = function(data) { var esri = rendererBackgroundSource(data), cache = {}; - esri.getVintage = function(center, tileCoord, callback) { + esri.getMetadata = function(center, tileCoord, callback) { var tileId = tileCoord.slice(0, 3).join('/'), zoom = Math.min(tileCoord[2], esri.scaleExtent[1]), centerPoint = center[0] + ',' + center[1], // long, lat (as it should be) @@ -268,9 +268,15 @@ rendererBackgroundSource.Esri = function(data) { return callback(null, cache[tileId].vintage); } - // accurate metadata is only available at zoom 13 and closer + // accurate metadata is only available >= 13 if (metadataLayer === 99) { - callback(null, { range: '', source: ' '}); + callback(null, { + range: 'Unknown', + source: 'Unknown', + description: 'Unknown', + resolution: 'Unknown', + accuracy: 'Unknown' + }); } else { jsonpRequest(url, function(result) { var err = !result || result.features.length < 1; @@ -280,9 +286,13 @@ rendererBackgroundSource.Esri = function(data) { var vintage = { // pass through the discrete capture date from metadata range: localeDateString(result.features[0].attributes.SRC_DATE2), - source: result.features[0].attributes.NICE_DESC + source: result.features[0].attributes.NICE_NAME, + description: result.features[0].attributes.NICE_DESC, + resolution: result.features[0].attributes.SRC_RES, + accuracy: result.features[0].attributes.SRC_ACC, + }; - + cache[tileId].vintage = vintage; return callback(null, vintage); } diff --git a/modules/renderer/tile_layer.js b/modules/renderer/tile_layer.js index 4a1735fa4..1e9927be2 100644 --- a/modules/renderer/tile_layer.js +++ b/modules/renderer/tile_layer.js @@ -255,7 +255,7 @@ export function rendererTileLayer(context) { .each(function(d) { var span = d3.select(this); var center = context.projection.invert(tileCenter(d)); - source.getVintage(center, d, function(err, result) { + source.getMetadata(center, d, function(err, result) { span.text((result && result.range) || t('info_panels.background.vintage') + ': ' + t('info_panels.background.unknown') ); diff --git a/modules/ui/panels/background.js b/modules/ui/panels/background.js index 9b5f6d303..393e5e8f4 100644 --- a/modules/ui/panels/background.js +++ b/modules/ui/panels/background.js @@ -8,7 +8,11 @@ export function uiPanelBackground(context) { var currSource = null; var currZoom = ''; var currVintage = ''; - var currEsriSource = ''; + + var currProvider = ''; + var currDescription = ''; + var currResolution = ''; + var currAccuracy = ''; function redraw(selection) { if (currSource !== background.baseLayerSource().name()) { @@ -42,7 +46,7 @@ export function uiPanelBackground(context) { .text(currVintage); if (!currVintage) { - debouncedGetVintage(selection); + debouncedGetMetadata(selection); } if (currSource === 'Esri World Imagery') { @@ -51,7 +55,25 @@ export function uiPanelBackground(context) { .text(t('info_panels.background.source') + ': ') .append('span') .attr('class', 'source') - .text(currEsriSource); + .text(currProvider); + list + .append('li') + .text(t('info_panels.background.description') + ': ') + .append('span') + .attr('class', 'description') + .text(currDescription); + list + .append('li') + .text(t('info_panels.background.resolution') + ': ') + .append('span') + .attr('class', 'resolution') + .text(currResolution); + list + .append('li') + .text(t('info_panels.background.accuracy') + ': ') + .append('span') + .attr('class', 'accuracy') + .text(currAccuracy); } var toggle = context.getDebug('tile') ? 'hide_tiles' : 'show_tiles'; @@ -68,8 +90,8 @@ export function uiPanelBackground(context) { } - var debouncedGetVintage = _.debounce(getVintage, 250); - function getVintage(selection) { + var debouncedGetMetadata = _.debounce(getMetadata, 250); + function getMetadata(selection) { var tile = d3.select('.layer-background img.tile-center'); // tile near viewport center if (tile.empty()) return; @@ -82,15 +104,24 @@ export function uiPanelBackground(context) { .text(currZoom); if (!d || !d.length >= 3) return; - background.baseLayerSource().getVintage(center, d, function(err, result) { + background.baseLayerSource().getMetadata(center, d, function(err, result) { currVintage = (result && result.range) || t('info_panels.background.unknown'); selection.selectAll('.vintage') .text(currVintage); // metadata from Esri can tell us the specific provider if (result.source) { - currEsriSource = result.source; + currSource = result.source; selection.selectAll('.source') - .text(currEsriSource); + .text(currSource); + currDescription = result.description; + selection.selectAll('.description') + .text(currDescription); + currResolution = result.resolution; + selection.selectAll('.resolution') + .text(currResolution + ' (m)'); + currAccuracy = result.accuracy; + selection.selectAll('.accuracy') + .text(currAccuracy + ' (m)'); } }); } @@ -104,7 +135,7 @@ export function uiPanelBackground(context) { selection.call(redraw); }) .on('move.info-background', function() { - selection.call(debouncedGetVintage); + selection.call(debouncedGetMetadata); }); }; diff --git a/modules/ui/status.js b/modules/ui/status.js index d9ba2bd0e..9d9dbc3e2 100644 --- a/modules/ui/status.js +++ b/modules/ui/status.js @@ -29,6 +29,7 @@ export function uiStatus(context) { osm.authenticate(); }); } else { + // eslint-disable-next-line no-warning-comments // TODO: nice messages for different error types selection.text(t('status.error')); } diff --git a/test/spec/spec_helpers.js b/test/spec/spec_helpers.js index 50fba97a4..083969397 100644 --- a/test/spec/spec_helpers.js +++ b/test/spec/spec_helpers.js @@ -20,4 +20,5 @@ mocha.setup({ }); expect = chai.expect; -var d3 = iD.d3; +// eslint-disable-next-line no-unused-vars +var d3 = iD.d3; \ No newline at end of file From fec27a04d3c59ba69720751e2689b950fb6892e4 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Mon, 11 Sep 2017 14:04:09 -0400 Subject: [PATCH 14/24] Add intermittent checkbox field, and Intermittent Stream preset --- data/presets.yaml | 8 ++ data/presets/fields.json | 5 ++ data/presets/fields/intermittent.json | 5 ++ data/presets/presets.json | 86 +++++++++++++++---- data/presets/presets/natural/spring.json | 4 + data/presets/presets/natural/water/lake.json | 7 +- data/presets/presets/natural/water/pond.json | 7 +- .../presets/natural/water/reservoir.json | 7 +- data/presets/presets/waterway/boatyard.json | 2 +- data/presets/presets/waterway/canal.json | 3 +- data/presets/presets/waterway/ditch.json | 3 +- data/presets/presets/waterway/drain.json | 3 +- data/presets/presets/waterway/river.json | 3 +- data/presets/presets/waterway/stream.json | 3 +- .../presets/waterway/stream_intermittent.json | 43 ++++++++++ data/presets/presets/waterway/waterfall.json | 3 +- data/taginfo.json | 4 + dist/locales/en.json | 7 ++ 18 files changed, 172 insertions(+), 31 deletions(-) create mode 100644 data/presets/fields/intermittent.json create mode 100644 data/presets/presets/waterway/stream_intermittent.json diff --git a/data/presets.yaml b/data/presets.yaml index 04310176e..0b87e42c4 100644 --- a/data/presets.yaml +++ b/data/presets.yaml @@ -630,6 +630,9 @@ en: inscription: # inscription=* label: Inscription + intermittent: + # intermittent=* + label: Intermittent internet_access: # internet_access=* label: Internet Access @@ -4876,6 +4879,11 @@ en: name: Stream # 'terms: beck,branch,brook,burn,course,creek,current,drift,flood,flow,freshet,race,rill,rindle,rivulet,run,runnel,rush,spate,spritz,surge,tide,torrent,tributary,watercourse' terms: '' + waterway/stream_intermittent: + # 'waterway=stream, intermittent=yes' + name: Intermittent Stream + # 'terms: arroyo,beck,branch,brook,burn,course,creek,drift,flood,flow,gully,run,runnel,rush,spate,spritz,tributary,wadi,wash,watercourse' + terms: '' waterway/water_point: # waterway=water_point name: Marine Drinking Water diff --git a/data/presets/fields.json b/data/presets/fields.json index cee4ba054..cf7684111 100644 --- a/data/presets/fields.json +++ b/data/presets/fields.json @@ -875,6 +875,11 @@ "type": "textarea", "label": "Inscription" }, + "intermittent": { + "key": "intermittent", + "type": "check", + "label": "Intermittent" + }, "internet_access": { "key": "internet_access", "type": "combo", diff --git a/data/presets/fields/intermittent.json b/data/presets/fields/intermittent.json new file mode 100644 index 000000000..ffbe6aaa1 --- /dev/null +++ b/data/presets/fields/intermittent.json @@ -0,0 +1,5 @@ +{ + "key": "intermittent", + "type": "check", + "label": "Intermittent" +} diff --git a/data/presets/presets.json b/data/presets/presets.json index 992217700..b3bdcc236 100644 --- a/data/presets/presets.json +++ b/data/presets/presets.json @@ -10035,6 +10035,10 @@ }, "natural/spring": { "icon": "water", + "fields": [ + "name", + "intermittent" + ], "geometry": [ "point", "vertex" @@ -10112,12 +10116,13 @@ }, "natural/water/lake": { "icon": "water", + "fields": [ + "name", + "intermittent" + ], "geometry": [ "area" ], - "fields": [ - "name" - ], "tags": { "natural": "water", "water": "lake" @@ -10135,12 +10140,13 @@ }, "natural/water/pond": { "icon": "water", + "fields": [ + "name", + "intermittent" + ], "geometry": [ "area" ], - "fields": [ - "name" - ], "tags": { "natural": "water", "water": "pond" @@ -10160,12 +10166,13 @@ }, "natural/water/reservoir": { "icon": "water", + "fields": [ + "name", + "intermittent" + ], "geometry": [ "area" ], - "fields": [ - "name" - ], "tags": { "natural": "water", "water": "reservoir" @@ -15268,7 +15275,8 @@ "icon": "waterway-canal", "fields": [ "name", - "width" + "width", + "intermittent" ], "geometry": [ "line" @@ -15297,7 +15305,8 @@ "waterway/ditch": { "icon": "waterway-ditch", "fields": [ - "tunnel_waterway" + "tunnel_waterway", + "intermittent" ], "geometry": [ "line" @@ -15333,7 +15342,8 @@ "waterway/drain": { "icon": "waterway-stream", "fields": [ - "tunnel_waterway" + "tunnel_waterway", + "intermittent" ], "geometry": [ "line" @@ -15372,7 +15382,8 @@ "fields": [ "name", "tunnel_waterway", - "width" + "width", + "intermittent" ], "geometry": [ "line" @@ -15438,12 +15449,56 @@ }, "name": "Marine Toilet Disposal" }, + "waterway/stream_intermittent": { + "icon": "waterway-stream", + "fields": [ + "name", + "tunnel_waterway", + "width", + "intermittent" + ], + "geometry": [ + "line" + ], + "terms": [ + "arroyo", + "beck", + "branch", + "brook", + "burn", + "course", + "creek", + "drift", + "flood", + "flow", + "gully", + "run", + "runnel", + "rush", + "spate", + "spritz", + "tributary", + "wadi", + "wash", + "watercourse" + ], + "tags": { + "waterway": "stream", + "intermittent": "yes" + }, + "reference": { + "key": "waterway", + "value": "stream" + }, + "name": "Intermittent Stream" + }, "waterway/stream": { "icon": "waterway-stream", "fields": [ "name", "tunnel_waterway", - "width" + "width", + "intermittent" ], "geometry": [ "line" @@ -15497,7 +15552,8 @@ "fields": [ "name", "height", - "width" + "width", + "intermittent" ], "geometry": [ "vertex" diff --git a/data/presets/presets/natural/spring.json b/data/presets/presets/natural/spring.json index 447110579..2292d40a0 100644 --- a/data/presets/presets/natural/spring.json +++ b/data/presets/presets/natural/spring.json @@ -1,5 +1,9 @@ { "icon": "water", + "fields": [ + "name", + "intermittent" + ], "geometry": [ "point", "vertex" diff --git a/data/presets/presets/natural/water/lake.json b/data/presets/presets/natural/water/lake.json index a35c5c50e..ea3bf28c0 100644 --- a/data/presets/presets/natural/water/lake.json +++ b/data/presets/presets/natural/water/lake.json @@ -1,11 +1,12 @@ { "icon": "water", + "fields": [ + "name", + "intermittent" + ], "geometry": [ "area" ], - "fields": [ - "name" - ], "tags": { "natural": "water", "water": "lake" diff --git a/data/presets/presets/natural/water/pond.json b/data/presets/presets/natural/water/pond.json index ef6aeaf08..21d246f5d 100644 --- a/data/presets/presets/natural/water/pond.json +++ b/data/presets/presets/natural/water/pond.json @@ -1,11 +1,12 @@ { "icon": "water", + "fields": [ + "name", + "intermittent" + ], "geometry": [ "area" ], - "fields": [ - "name" - ], "tags": { "natural": "water", "water": "pond" diff --git a/data/presets/presets/natural/water/reservoir.json b/data/presets/presets/natural/water/reservoir.json index 6fba02ecb..274c721e2 100644 --- a/data/presets/presets/natural/water/reservoir.json +++ b/data/presets/presets/natural/water/reservoir.json @@ -1,11 +1,12 @@ { "icon": "water", + "fields": [ + "name", + "intermittent" + ], "geometry": [ "area" ], - "fields": [ - "name" - ], "tags": { "natural": "water", "water": "reservoir" diff --git a/data/presets/presets/waterway/boatyard.json b/data/presets/presets/waterway/boatyard.json index 919354792..a445dd6d7 100644 --- a/data/presets/presets/waterway/boatyard.json +++ b/data/presets/presets/waterway/boatyard.json @@ -1,7 +1,7 @@ { "icon": "harbor", "fields":[ - "name", + "name", "operator" ], "geometry": [ diff --git a/data/presets/presets/waterway/canal.json b/data/presets/presets/waterway/canal.json index 6cab011d8..2b22b0f57 100644 --- a/data/presets/presets/waterway/canal.json +++ b/data/presets/presets/waterway/canal.json @@ -2,7 +2,8 @@ "icon": "waterway-canal", "fields": [ "name", - "width" + "width", + "intermittent" ], "geometry": [ "line" diff --git a/data/presets/presets/waterway/ditch.json b/data/presets/presets/waterway/ditch.json index 9373764b1..e5ff49863 100644 --- a/data/presets/presets/waterway/ditch.json +++ b/data/presets/presets/waterway/ditch.json @@ -1,7 +1,8 @@ { "icon": "waterway-ditch", "fields": [ - "tunnel_waterway" + "tunnel_waterway", + "intermittent" ], "geometry": [ "line" diff --git a/data/presets/presets/waterway/drain.json b/data/presets/presets/waterway/drain.json index 71f63d634..614284713 100644 --- a/data/presets/presets/waterway/drain.json +++ b/data/presets/presets/waterway/drain.json @@ -1,7 +1,8 @@ { "icon": "waterway-stream", "fields": [ - "tunnel_waterway" + "tunnel_waterway", + "intermittent" ], "geometry": [ "line" diff --git a/data/presets/presets/waterway/river.json b/data/presets/presets/waterway/river.json index 3125600e2..a4448bf67 100644 --- a/data/presets/presets/waterway/river.json +++ b/data/presets/presets/waterway/river.json @@ -3,7 +3,8 @@ "fields": [ "name", "tunnel_waterway", - "width" + "width", + "intermittent" ], "geometry": [ "line" diff --git a/data/presets/presets/waterway/stream.json b/data/presets/presets/waterway/stream.json index 802924646..3b26a9436 100644 --- a/data/presets/presets/waterway/stream.json +++ b/data/presets/presets/waterway/stream.json @@ -3,7 +3,8 @@ "fields": [ "name", "tunnel_waterway", - "width" + "width", + "intermittent" ], "geometry": [ "line" diff --git a/data/presets/presets/waterway/stream_intermittent.json b/data/presets/presets/waterway/stream_intermittent.json new file mode 100644 index 000000000..e6ff48837 --- /dev/null +++ b/data/presets/presets/waterway/stream_intermittent.json @@ -0,0 +1,43 @@ +{ + "icon": "waterway-stream", + "fields": [ + "name", + "tunnel_waterway", + "width", + "intermittent" + ], + "geometry": [ + "line" + ], + "terms": [ + "arroyo", + "beck", + "branch", + "brook", + "burn", + "course", + "creek", + "drift", + "flood", + "flow", + "gully", + "run", + "runnel", + "rush", + "spate", + "spritz", + "tributary", + "wadi", + "wash", + "watercourse" + ], + "tags": { + "waterway": "stream", + "intermittent": "yes" + }, + "reference": { + "key": "waterway", + "value": "stream" + }, + "name": "Intermittent Stream" +} diff --git a/data/presets/presets/waterway/waterfall.json b/data/presets/presets/waterway/waterfall.json index 2081e6a37..d87e625dc 100644 --- a/data/presets/presets/waterway/waterfall.json +++ b/data/presets/presets/waterway/waterfall.json @@ -3,7 +3,8 @@ "fields": [ "name", "height", - "width" + "width", + "intermittent" ], "geometry": [ "vertex" diff --git a/data/taginfo.json b/data/taginfo.json index 01c8c176c..757d03e6b 100644 --- a/data/taginfo.json +++ b/data/taginfo.json @@ -3062,6 +3062,10 @@ "key": "waterway", "value": "sanitary_dump_station" }, + { + "key": "intermittent", + "value": "yes" + }, { "key": "waterway", "value": "stream" diff --git a/dist/locales/en.json b/dist/locales/en.json index 6dd81dd60..8237da0df 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -1619,6 +1619,9 @@ "inscription": { "label": "Inscription" }, + "intermittent": { + "label": "Intermittent" + }, "internet_access": { "label": "Internet Access", "options": { @@ -5385,6 +5388,10 @@ "name": "Marine Toilet Disposal", "terms": "Boat,Watercraft,Sanitary,Dump Station,Pumpout,Pump out,Elsan,CDP,CTDP,Chemical Toilet" }, + "waterway/stream_intermittent": { + "name": "Intermittent Stream", + "terms": "arroyo,beck,branch,brook,burn,course,creek,drift,flood,flow,gully,run,runnel,rush,spate,spritz,tributary,wadi,wash,watercourse" + }, "waterway/stream": { "name": "Stream", "terms": "beck,branch,brook,burn,course,creek,current,drift,flood,flow,freshet,race,rill,rindle,rivulet,run,runnel,rush,spate,spritz,surge,tide,torrent,tributary,watercourse" From 494e247ad1ec458d0d2bed6102dd5deb90eb11aa Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Mon, 11 Sep 2017 14:14:15 -0400 Subject: [PATCH 15/24] Render intermittent features with dashed lines --- modules/svg/tag_classes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/svg/tag_classes.js b/modules/svg/tag_classes.js index be2d6720c..d7bfa43af 100644 --- a/modules/svg/tag_classes.js +++ b/modules/svg/tag_classes.js @@ -10,7 +10,7 @@ export function svgTagClasses() { ], statuses = [ 'proposed', 'construction', 'disused', 'abandoned', 'dismantled', - 'razed', 'demolished', 'obliterated' + 'razed', 'demolished', 'obliterated', 'intermittent' ], secondaries = [ 'oneway', 'bridge', 'tunnel', 'embankment', 'cutting', 'barrier', From 59f1df902d29ce4bb4077bec2e58d5ed0cb6ffad Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Mon, 11 Sep 2017 15:16:02 -0400 Subject: [PATCH 16/24] When showing a field, set its default value if it has one This allows universal fields or other standalone fields to have a default value. This didn't work before becuase default values were only handled by preset.applyTags() / preset.removeTags(). --- modules/ui/field.js | 15 ++++++++++++--- modules/ui/form_fields.js | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/modules/ui/field.js b/modules/ui/field.js index ee70f98c5..d2c34ebd8 100644 --- a/modules/ui/field.js +++ b/modules/ui/field.js @@ -18,6 +18,7 @@ export function uiField(context, presetField, entity, options) { var dispatch = d3.dispatch('change'), field = _.clone(presetField), + show = options.show, state = '', tags = {}; @@ -33,8 +34,6 @@ export function uiField(context, presetField, entity, options) { field.keys = field.keys || [field.key]; - field.show = options.show; - function isModified() { if (!entity) return false; @@ -176,8 +175,18 @@ export function uiField(context, presetField, entity, options) { }; + field.show = function() { + show = true; + if (field.default && field.key && tags[field.key] !== field.default) { + var t = {}; + t[field.key] = field.default; + dispatch.call('change', this, t); + } + }; + + field.isShown = function() { - return field.show || _.some(field.keys, function(key) { return !!tags[key]; }); + return show || _.some(field.keys, function(key) { return !!tags[key]; }); }; diff --git a/modules/ui/form_fields.js b/modules/ui/form_fields.js index bcb234558..25876376b 100644 --- a/modules/ui/form_fields.js +++ b/modules/ui/form_fields.js @@ -101,7 +101,7 @@ export function uiFormFields(context) { .minItems(1) .on('accept', function (d) { var field = d.field; - field.show = true; + field.show(); render(selection); if (field.type !== 'semiCombo' && field.type !== 'multiCombo') { field.focus(); From 19e9d57e49c000c56aeb870e88e08df78dacac0a Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Mon, 11 Sep 2017 15:20:03 -0400 Subject: [PATCH 17/24] Add tourism=attraction as a universal field (closes #4323) --- data/presets.yaml | 3 +++ data/presets/fields.json | 7 +++++++ data/presets/fields/tourism_attraction.json | 7 +++++++ dist/locales/en.json | 3 +++ 4 files changed, 20 insertions(+) create mode 100644 data/presets/fields/tourism_attraction.json diff --git a/data/presets.yaml b/data/presets.yaml index 0b87e42c4..f2c42f20c 100644 --- a/data/presets.yaml +++ b/data/presets.yaml @@ -1350,6 +1350,9 @@ en: tourism: # tourism=* label: Type + tourism_attraction: + # tourism=* + label: Tourism tower/construction: # 'tower:construction=*' label: Construction diff --git a/data/presets/fields.json b/data/presets/fields.json index cf7684111..2c7232020 100644 --- a/data/presets/fields.json +++ b/data/presets/fields.json @@ -1836,6 +1836,13 @@ "type": "typeCombo", "label": "Type" }, + "tourism_attraction": { + "key": "tourism", + "default": "attraction", + "type": "typeCombo", + "universal": true, + "label": "Tourism" + }, "tourism": { "key": "tourism", "type": "typeCombo", diff --git a/data/presets/fields/tourism_attraction.json b/data/presets/fields/tourism_attraction.json new file mode 100644 index 000000000..2fa8f8f9d --- /dev/null +++ b/data/presets/fields/tourism_attraction.json @@ -0,0 +1,7 @@ +{ + "key": "tourism", + "default": "attraction", + "type": "typeCombo", + "universal": true, + "label": "Tourism" +} diff --git a/dist/locales/en.json b/dist/locales/en.json index 8237da0df..94691023f 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -2206,6 +2206,9 @@ "tomb": { "label": "Type" }, + "tourism_attraction": { + "label": "Tourism" + }, "tourism": { "label": "Type" }, From 4032904a7b911769b39f32a490060e687cd09446 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Mon, 11 Sep 2017 17:11:20 -0400 Subject: [PATCH 18/24] Fix mapillary detection label positions (closes #4282) --- css/60_mapillary.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/css/60_mapillary.css b/css/60_mapillary.css index 1bf059689..a3067ea7e 100644 --- a/css/60_mapillary.css +++ b/css/60_mapillary.css @@ -73,7 +73,7 @@ background-color: rgba(0, 0, 0, 0.4); padding: 0 4px; border-radius: 4px; - transform: translate(-50%, -120%) !important; + top: -25px; } #mly .domRenderer .Attribution { From 6addbba3400dbeeb54b2af7f704845202b1f953c Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Tue, 12 Sep 2017 14:51:01 -0400 Subject: [PATCH 19/24] reorganize metadata object, change display of meters --- dist/locales/en.json | 4 + modules/renderer/background_source.js | 103 ++++++++++++-------- modules/renderer/tile_layer.js | 2 +- modules/ui/panels/background.js | 131 +++++++++++--------------- 4 files changed, 127 insertions(+), 113 deletions(-) diff --git a/dist/locales/en.json b/dist/locales/en.json index 94691023f..cb0b2a075 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -354,6 +354,10 @@ "title": "Background", "zoom": "Zoom", "vintage": "Vintage", + "source": "Source", + "description": "Description", + "resolution": "Resolution", + "accuracy": "Accuracy", "unknown": "Unknown", "show_tiles": "Show Tiles", "hide_tiles": "Hide Tiles" diff --git a/modules/renderer/background_source.js b/modules/renderer/background_source.js index 1a0814f21..cb2f454d0 100644 --- a/modules/renderer/background_source.js +++ b/modules/renderer/background_source.js @@ -139,7 +139,9 @@ export function rendererBackgroundSource(data) { end: localeDateString(source.endDate) }; vintage.range = vintageRange(vintage); - callback(null, vintage); + + var metadata = { vintage: vintage }; + callback(null, metadata); }; @@ -200,8 +202,8 @@ rendererBackgroundSource.Bing = function(data, dispatch) { if (!cache[tileId]) { cache[tileId] = {}; } - if (cache[tileId] && cache[tileId].vintage) { - return callback(null, cache[tileId].vintage); + if (cache[tileId] && cache[tileId].metadata) { + return callback(null, cache[tileId].metadata); } jsonpRequest(url, function(result) { @@ -214,8 +216,10 @@ rendererBackgroundSource.Bing = function(data, dispatch) { end: localeDateString(result.resourceSets[0].resources[0].vintageEnd) }; vintage.range = vintageRange(vintage); - cache[tileId].vintage = vintage; - return callback(null, vintage); + + var metadata = { vintage: vintage }; + cache[tileId].metadata = metadata; + return callback(null, metadata); } }); }; @@ -244,57 +248,82 @@ rendererBackgroundSource.Esri = function(data) { var tileId = tileCoord.slice(0, 3).join('/'), zoom = Math.min(tileCoord[2], esri.scaleExtent[1]), centerPoint = center[0] + ',' + center[1], // long, lat (as it should be) - metadataLayer; - switch (true) { - case zoom >= 19: - metadataLayer = 3; - break; - case zoom >= 17: - metadataLayer = 2; - break; - case zoom >= 13: - metadataLayer = 0; - break; - default: - metadataLayer = 99; - } - // build up query using the layer appropriate to the current zoom - var url = 'https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/' + metadataLayer + '/query?returnGeometry=false&geometry=' + centerPoint + '&inSR=4326&geometryType=esriGeometryPoint&outFields=*&f=json&callback={callback}'; + metadataLayer, + vintage = {}, + metadata = {}; + + switch (true) { + case zoom >= 19: + metadataLayer = 3; + break; + case zoom >= 17: + metadataLayer = 2; + break; + case zoom >= 13: + metadataLayer = 0; + break; + default: + metadataLayer = 99; + } + + // build up query using the layer appropriate to the current zoom + var url = 'https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/' + metadataLayer + '/query?returnGeometry=false&geometry=' + centerPoint + '&inSR=4326&geometryType=esriGeometryPoint&outFields=*&f=json&callback={callback}'; if (!cache[tileId]) { cache[tileId] = {}; } - if (cache[tileId] && cache[tileId].vintage) { - return callback(null, cache[tileId].vintage); + if (cache[tileId] && cache[tileId].metadata) { + return callback(null, cache[tileId].metadata); } // accurate metadata is only available >= 13 if (metadataLayer === 99) { - callback(null, { - range: 'Unknown', - source: 'Unknown', - description: 'Unknown', - resolution: 'Unknown', - accuracy: 'Unknown' - }); + vintage = { + start: null, + end: null, + range: null + }; + metadata = { + vintage: null, + source: t('info_panels.background.unknown'), + description: t('info_panels.background.unknown'), + resolution: t('info_panels.background.unknown'), + accuracy: t('info_panels.background.unknown') + }; + + callback(null, metadata); + } else { jsonpRequest(url, function(result) { - var err = !result || result.features.length < 1; + var err; + if (!result) { + err = 'Unknown Error'; + } else if (result.features && result.features.length < 1) { + err = 'No Results'; + } else if (result.error && result.error.message) { + err = result.error.message; + } + if (err) { return callback(err); } else { - var vintage = { - // pass through the discrete capture date from metadata - range: localeDateString(result.features[0].attributes.SRC_DATE2), + // pass through the discrete capture date from metadata + var captureDate = localeDateString(result.features[0].attributes.SRC_DATE2); + vintage = { + start: captureDate, + end: captureDate, + range: captureDate + }; + metadata = { + vintage: vintage, source: result.features[0].attributes.NICE_NAME, description: result.features[0].attributes.NICE_DESC, resolution: result.features[0].attributes.SRC_RES, accuracy: result.features[0].attributes.SRC_ACC, - }; - cache[tileId].vintage = vintage; - return callback(null, vintage); + cache[tileId].metadata = metadata; + return callback(null, metadata); } }); } diff --git a/modules/renderer/tile_layer.js b/modules/renderer/tile_layer.js index 1e9927be2..88f2d9141 100644 --- a/modules/renderer/tile_layer.js +++ b/modules/renderer/tile_layer.js @@ -256,7 +256,7 @@ export function rendererTileLayer(context) { var span = d3.select(this); var center = context.projection.invert(tileCenter(d)); source.getMetadata(center, d, function(err, result) { - span.text((result && result.range) || + span.text((result && result.vintage && result.vintage.range) || t('info_panels.background.vintage') + ': ' + t('info_panels.background.unknown') ); }); diff --git a/modules/ui/panels/background.js b/modules/ui/panels/background.js index 393e5e8f4..c6e867a79 100644 --- a/modules/ui/panels/background.js +++ b/modules/ui/panels/background.js @@ -5,20 +5,18 @@ import { t } from '../../util/locale'; export function uiPanelBackground(context) { var background = context.background(); - var currSource = null; - var currZoom = ''; - var currVintage = ''; + var currSourceName = null; + var metadata = { zoom: '', vintage: '' }; + var metadataKeys = [ + 'zoom', 'vintage', 'source', 'description', 'resolution', 'accuracy' + ]; - var currProvider = ''; - var currDescription = ''; - var currResolution = ''; - var currAccuracy = ''; + var debouncedRedraw = _.debounce(redraw, 250); function redraw(selection) { - if (currSource !== background.baseLayerSource().name()) { - currSource = background.baseLayerSource().name(); - currZoom = ''; - currVintage = ''; + if (currSourceName !== background.baseLayerSource().name()) { + currSourceName = background.baseLayerSource().name(); + metadata = { zoom: '', vintage: '' }; } selection.html(''); @@ -29,52 +27,23 @@ export function uiPanelBackground(context) { list .append('li') - .text(currSource); + .text(currSourceName); - list - .append('li') - .text(t('info_panels.background.zoom') + ': ') - .append('span') - .attr('class', 'zoom') - .text(currZoom); + metadataKeys.forEach(function(k) { + list + .append('li') + .attr('class', 'background-info-list-' + k) + .classed('hide', !metadata[k]) + .text(t('info_panels.background.' + k) + ': ') + .append('span') + .attr('class', 'background-info-span-' + k) + .text(metadata[k]); + }); - list - .append('li') - .text(t('info_panels.background.vintage') + ': ') - .append('span') - .attr('class', 'vintage') - .text(currVintage); - - if (!currVintage) { + if (!metadata.vintage) { debouncedGetMetadata(selection); } - if (currSource === 'Esri World Imagery') { - list - .append('li') - .text(t('info_panels.background.source') + ': ') - .append('span') - .attr('class', 'source') - .text(currProvider); - list - .append('li') - .text(t('info_panels.background.description') + ': ') - .append('span') - .attr('class', 'description') - .text(currDescription); - list - .append('li') - .text(t('info_panels.background.resolution') + ': ') - .append('span') - .attr('class', 'resolution') - .text(currResolution); - list - .append('li') - .text(t('info_panels.background.accuracy') + ': ') - .append('span') - .attr('class', 'accuracy') - .text(currAccuracy); - } var toggle = context.getDebug('tile') ? 'hide_tiles' : 'show_tiles'; selection @@ -91,38 +60,50 @@ export function uiPanelBackground(context) { var debouncedGetMetadata = _.debounce(getMetadata, 250); + function getMetadata(selection) { var tile = d3.select('.layer-background img.tile-center'); // tile near viewport center if (tile.empty()) return; - var d = tile.datum(), + var sourceName = currSourceName, + d = tile.datum(), zoom = (d && d.length >= 3 && d[2]) || Math.floor(context.map().zoom()), center = context.map().center(); - currZoom = String(zoom); - selection.selectAll('.zoom') - .text(currZoom); + // update zoom + metadata.zoom = String(zoom); + selection.selectAll('.background-info-span-zoom') + .text(metadata.zoom); if (!d || !d.length >= 3) return; + background.baseLayerSource().getMetadata(center, d, function(err, result) { - currVintage = (result && result.range) || t('info_panels.background.unknown'); - selection.selectAll('.vintage') - .text(currVintage); - // metadata from Esri can tell us the specific provider - if (result.source) { - currSource = result.source; - selection.selectAll('.source') - .text(currSource); - currDescription = result.description; - selection.selectAll('.description') - .text(currDescription); - currResolution = result.resolution; - selection.selectAll('.resolution') - .text(currResolution + ' (m)'); - currAccuracy = result.accuracy; - selection.selectAll('.accuracy') - .text(currAccuracy + ' (m)'); - } + if (err || currSourceName !== sourceName) return; + + // update vintage + var vintage = result.vintage; + metadata.vintage = (vintage && vintage.range) || t('info_panels.background.unknown'); + selection.selectAll('.background-info-span-vintage') + .text(metadata.vintage); + + // update other metdata + _.without(metadataKeys, 'zoom', 'vintage') + .forEach(function(k) { + var val = result[k]; + + // append units to numeric data + if (k === 'resolution' || k === 'accuracy') { + if (val && isFinite(val)) { + val += ' m'; + } + } + + metadata[k] = val; + selection.selectAll('.background-info-list-' + k) + .classed('hide', !val) + .selectAll('.background-info-span-' + k) + .text(val); + }); }); } @@ -132,7 +113,7 @@ export function uiPanelBackground(context) { context.map() .on('drawn.info-background', function() { - selection.call(redraw); + selection.call(debouncedRedraw); }) .on('move.info-background', function() { selection.call(debouncedGetMetadata); From 9d60d9c6b02c2c1d2e04f3945613d022a13c7b02 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Tue, 12 Sep 2017 15:00:32 -0400 Subject: [PATCH 20/24] Track inflight jsonp requests and avoid reissuing them --- modules/renderer/background_source.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/modules/renderer/background_source.js b/modules/renderer/background_source.js index cb2f454d0..0451131e4 100644 --- a/modules/renderer/background_source.js +++ b/modules/renderer/background_source.js @@ -160,6 +160,7 @@ rendererBackgroundSource.Bing = function(data, dispatch) { url = 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial?include=ImageryProviders&key=' + key + '&jsonp={callback}', cache = {}, + inflight = {}, providers = []; jsonpRequest(url, function(json) { @@ -199,6 +200,8 @@ rendererBackgroundSource.Bing = function(data, dispatch) { url = 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial/' + centerPoint + '?zl=' + zoom + '&key=' + key + '&jsonp={callback}'; + if (inflight[tileId]) return; + if (!cache[tileId]) { cache[tileId] = {}; } @@ -206,7 +209,10 @@ rendererBackgroundSource.Bing = function(data, dispatch) { return callback(null, cache[tileId].metadata); } + inflight[tileId] = true; jsonpRequest(url, function(result) { + delete inflight[tileId]; + var err = (!result && 'Unknown Error') || result.errorDetails; if (err) { return callback(err); @@ -242,7 +248,8 @@ rendererBackgroundSource.Esri = function(data) { } var esri = rendererBackgroundSource(data), - cache = {}; + cache = {}, + inflight = {}; esri.getMetadata = function(center, tileCoord, callback) { var tileId = tileCoord.slice(0, 3).join('/'), @@ -252,6 +259,8 @@ rendererBackgroundSource.Esri = function(data) { vintage = {}, metadata = {}; + if (inflight[tileId]) return; + switch (true) { case zoom >= 19: metadataLayer = 3; @@ -294,7 +303,10 @@ rendererBackgroundSource.Esri = function(data) { callback(null, metadata); } else { + inflight[tileId] = true; jsonpRequest(url, function(result) { + delete inflight[tileId]; + var err; if (!result) { err = 'Unknown Error'; From 75fcb892f83cd8b1b3741827a1929eaec193f0db Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Tue, 12 Sep 2017 15:32:23 -0400 Subject: [PATCH 21/24] Fix show/hide of list items --- modules/ui/panels/background.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/modules/ui/panels/background.js b/modules/ui/panels/background.js index c6e867a79..04bfae05b 100644 --- a/modules/ui/panels/background.js +++ b/modules/ui/panels/background.js @@ -6,7 +6,7 @@ import { t } from '../../util/locale'; export function uiPanelBackground(context) { var background = context.background(); var currSourceName = null; - var metadata = { zoom: '', vintage: '' }; + var metadata = {}; var metadataKeys = [ 'zoom', 'vintage', 'source', 'description', 'resolution', 'accuracy' ]; @@ -16,7 +16,7 @@ export function uiPanelBackground(context) { function redraw(selection) { if (currSourceName !== background.baseLayerSource().name()) { currSourceName = background.baseLayerSource().name(); - metadata = { zoom: '', vintage: '' }; + metadata = {}; } selection.html(''); @@ -40,7 +40,7 @@ export function uiPanelBackground(context) { .text(metadata[k]); }); - if (!metadata.vintage) { + if (!metadata.zoom) { debouncedGetMetadata(selection); } @@ -72,7 +72,9 @@ export function uiPanelBackground(context) { // update zoom metadata.zoom = String(zoom); - selection.selectAll('.background-info-span-zoom') + selection.selectAll('.background-info-list-zoom') + .classed('hide', false) + .selectAll('.background-info-span-zoom') .text(metadata.zoom); if (!d || !d.length >= 3) return; @@ -83,7 +85,9 @@ export function uiPanelBackground(context) { // update vintage var vintage = result.vintage; metadata.vintage = (vintage && vintage.range) || t('info_panels.background.unknown'); - selection.selectAll('.background-info-span-vintage') + selection.selectAll('.background-info-list-vintage') + .classed('hide', false) + .selectAll('.background-info-span-vintage') .text(metadata.vintage); // update other metdata From 72b9e4413f3a807b38d949660ae27c0e959167dc Mon Sep 17 00:00:00 2001 From: Hugo Date: Tue, 12 Sep 2017 23:16:06 +0300 Subject: [PATCH 22/24] HTTPS links and a typo --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 70a0cef23..02ea26062 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ -# iD - friendly JavaScript editor for [OpenStreetMap](http://www.openstreetmap.org/) +# iD - friendly JavaScript editor for [OpenStreetMap](https://www.openstreetmap.org/) [![Build Status](https://travis-ci.org/openstreetmap/iD.svg?branch=master)](https://travis-ci.org/openstreetmap/iD) [![Greenkeeper badge](https://badges.greenkeeper.io/openstreetmap/iD.svg)](https://greenkeeper.io/) ## Basics -* iD is a JavaScript [OpenStreetMap](http://www.openstreetmap.org/) editor. +* iD is a JavaScript [OpenStreetMap](https://www.openstreetmap.org/) editor. * It's intentionally simple. It lets you do the most basic tasks while not breaking other people's data. * It supports all popular modern desktop browsers: Chrome, Firefox, Safari, @@ -27,9 +27,9 @@ if you're looking for something to do. Come on in, the water's lovely. More help? Ping `jfire` or `bhousel` on: * [OpenStreetMap US Slack](https://osmus-slack.herokuapp.com/) (`#dev` or `#general` channels) -* [OpenStreetMap IRC](http://wiki.openstreetmap.org/wiki/IRC) +* [OpenStreetMap IRC](https://wiki.openstreetmap.org/wiki/IRC) (`irc.oftc.net`, in `#iD` or `#osm-dev` or `#osm`) -* [OpenStreetMap `dev` mailing list](http://wiki.openstreetmap.org/wiki/Mailing_lists) +* [OpenStreetMap `dev` mailing list](https://wiki.openstreetmap.org/wiki/Mailing_lists) ## Prerequisites @@ -50,7 +50,7 @@ To run the current development version of iD on your own computer: #### Cloning the repository -The repository is reasonably large. and it's unlikely that you need the full history. If you are happy to wait for it all to download, run: +The repository is reasonably large, and it's unlikely that you need the full history. If you are happy to wait for it all to download, run: ``` git clone https://github.com/openstreetmap/iD.git @@ -65,6 +65,7 @@ git clone --depth=1 https://github.com/openstreetmap/iD.git If you want to add in the full history later on, perhaps to run `git blame` or `git log`, run `git fetch --depth=1000000` #### Building iD + 1. `cd` into the newly cloned project folder 2. Run `npm install` 3. Run `npm run all` From 1fcceeb0e89d5b8fb30f83c3fff6060937de4ff7 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Tue, 12 Sep 2017 17:02:17 -0400 Subject: [PATCH 23/24] Move string processing into background_source --- modules/renderer/background_source.js | 31 ++++++++++++++++++++------- modules/ui/panels/background.js | 12 +---------- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/modules/renderer/background_source.js b/modules/renderer/background_source.js index 0451131e4..7e7fc7019 100644 --- a/modules/renderer/background_source.js +++ b/modules/renderer/background_source.js @@ -255,6 +255,7 @@ rendererBackgroundSource.Esri = function(data) { var tileId = tileCoord.slice(0, 3).join('/'), zoom = Math.min(tileCoord[2], esri.scaleExtent[1]), centerPoint = center[0] + ',' + center[1], // long, lat (as it should be) + unknown = t('info_panels.background.unknown'), metadataLayer, vintage = {}, metadata = {}; @@ -294,10 +295,10 @@ rendererBackgroundSource.Esri = function(data) { }; metadata = { vintage: null, - source: t('info_panels.background.unknown'), - description: t('info_panels.background.unknown'), - resolution: t('info_panels.background.unknown'), - accuracy: t('info_panels.background.unknown') + source: unknown, + description: unknown, + resolution: unknown, + accuracy: unknown }; callback(null, metadata); @@ -328,14 +329,28 @@ rendererBackgroundSource.Esri = function(data) { }; metadata = { vintage: vintage, - source: result.features[0].attributes.NICE_NAME, - description: result.features[0].attributes.NICE_DESC, - resolution: result.features[0].attributes.SRC_RES, - accuracy: result.features[0].attributes.SRC_ACC, + source: clean(result.features[0].attributes.NICE_NAME), + description: clean(result.features[0].attributes.NICE_DESC), + resolution: clean(result.features[0].attributes.SRC_RES), + accuracy: clean(result.features[0].attributes.SRC_ACC) }; + // append units - meters + if (isFinite(metadata.resolution)) { + metadata.resolution += ' m'; + } + if (isFinite(metadata.accuracy)) { + metadata.accuracy += ' m'; + } + cache[tileId].metadata = metadata; return callback(null, metadata); + + + function clean(val) { + return String(val).trim() || unknown; + } + } }); } diff --git a/modules/ui/panels/background.js b/modules/ui/panels/background.js index 04bfae05b..a17146d9f 100644 --- a/modules/ui/panels/background.js +++ b/modules/ui/panels/background.js @@ -40,9 +40,7 @@ export function uiPanelBackground(context) { .text(metadata[k]); }); - if (!metadata.zoom) { - debouncedGetMetadata(selection); - } + debouncedGetMetadata(selection); var toggle = context.getDebug('tile') ? 'hide_tiles' : 'show_tiles'; @@ -94,14 +92,6 @@ export function uiPanelBackground(context) { _.without(metadataKeys, 'zoom', 'vintage') .forEach(function(k) { var val = result[k]; - - // append units to numeric data - if (k === 'resolution' || k === 'accuracy') { - if (val && isFinite(val)) { - val += ' m'; - } - } - metadata[k] = val; selection.selectAll('.background-info-list-' + k) .classed('hide', !val) From 12be1a8161cd9178b842c2f465f666484387707f Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Wed, 13 Sep 2017 09:03:16 -0400 Subject: [PATCH 24/24] pacify eslint --- modules/renderer/background_source.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/modules/renderer/background_source.js b/modules/renderer/background_source.js index 7e7fc7019..5fbbfca8a 100644 --- a/modules/renderer/background_source.js +++ b/modules/renderer/background_source.js @@ -345,15 +345,14 @@ rendererBackgroundSource.Esri = function(data) { cache[tileId].metadata = metadata; return callback(null, metadata); - - - function clean(val) { - return String(val).trim() || unknown; - } - } }); } + + + function clean(val) { + return String(val).trim() || unknown; + } }; return esri;