diff --git a/css/30_highways.css b/css/30_highways.css index cb000b1d7..b29485a92 100644 --- a/css/30_highways.css +++ b/css/30_highways.css @@ -489,7 +489,7 @@ path.line.stroke.tag-highway_bus_stop, .preset-icon-container path.casing.tag-highway-footway { stroke: #988; } -.preset-icon-container path.stroke.tag-highway-footway:not(.tag-footway-crossing):not(.tag-man_made-pier):not(.tag-public_transport-platform) { +.preset-icon-container path.stroke.tag-highway-footway:not(.tag-crossing-marked):not(.tag-crossing-unmarked):not(.tag-man_made-pier):not(.tag-public_transport-platform) { stroke: #fff; } @@ -576,12 +576,21 @@ path.line.stroke.tag-highway.tag-crossing-marked { path.line.stroke.tag-highway-footway.tag-crossing-marked { stroke: #4c4444; } +.preset-icon .icon.tag-highway-footway.tag-crossing-marked { + color: #4c4444; +} path.line.stroke.tag-highway-footway.tag-crossing-unmarked { stroke: #776a6a; } +.preset-icon .icon.tag-highway-footway.tag-crossing-unmarked { + color: #776a6a; +} path.line.stroke.tag-highway-cycleway.tag-crossing-marked { stroke: #446077; } +.preset-icon .icon.tag-highway-cycleway.tag-crossing-marked { + color: #446077; +} /* highway midpoints */ diff --git a/data/core.yaml b/data/core.yaml index bfd36e8f5..c28e1ed36 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -1306,6 +1306,12 @@ en: tip: "Find features that should possibly be connected to other nearby features" highway-highway: reference: Intersecting highways should share a junction vertex. + close_nodes: + title: "Very Close Points" + message: "Two points in {way} are very close together" + tip: "Find redundant points in ways" + ref_merge: "Nodes are less than 2 meters away; you may want to merge them." + ref_move_away: "Nodes are less than 2 meters away but not mergable; you may want to move them further apart." crossing_ways: title: Crossings Ways message: "{feature} crosses {feature2}" @@ -1412,7 +1418,7 @@ en: message: "{feature} flows away from a connected waterway" end: message: "{feature} flows against a connected waterway" - reference: "Waterway segements should all flow in the same direction." + reference: "Waterway segments should all flow in the same direction." highway: start: message: "{feature} is unreachable" @@ -1444,6 +1450,8 @@ en: title: Delete this feature ignore_issue: title: Ignore this issue + merge_points: + title: Merge these points move_tags: title: Move the tags annotation: Moved tags. diff --git a/data/presets.yaml b/data/presets.yaml index 0ad3e05b7..3263c85ec 100644 --- a/data/presets.yaml +++ b/data/presets.yaml @@ -4184,6 +4184,9 @@ en: name: Indoor Corridor # 'terms: gallery,hall,hallway,indoor,passage,passageway' terms: '' + highway/crossing: + # highway=crossing + name: Crossing highway/crossing/marked: # crossing=marked name: Marked Crosswalk @@ -4195,11 +4198,11 @@ en: # 'terms: zebra crossing,marked crossing,crosswalk,flat top,hump,speed,slow' terms: '' highway/crossing/unmarked: - # highway=crossing + # crossing=unmarked name: Unmarked Crossing terms: '' highway/crossing/unmarked-raised: - # 'highway=crossing, traffic_calming=table' + # 'highway=crossing, crossing=unmarked, traffic_calming=table' name: Unmarked Crossing (Raised) # 'terms: flat top,hump,speed,slow' terms: '' @@ -4219,13 +4222,16 @@ en: name: Cycle & Foot Path # 'terms: bicycle and foot path,mixed-use trail,multi-use trail,segregated trail' terms: '' + highway/cycleway/crossing: + # cycleway=crossing + name: Cycle Crossing highway/cycleway/crossing/marked: # 'cycleway=crossing, crossing=marked' name: Marked Cycle Crossing # 'terms: cycle crosswalk,cycle path crossing,cycleway crossing,bicycle crossing,bike crossing' terms: '' highway/cycleway/crossing/unmarked: - # cycleway=crossing + # 'cycleway=crossing, crossing=unmarked' name: Unmarked Cycle Crossing # 'terms: cycle path crossing,cycleway crossing,bicycle crossing,bike crossing' terms: '' @@ -4244,6 +4250,9 @@ en: name: Moving Walkway # 'terms: moving sidewalk,autwalk,skywalk,travolator,travelator,travellator,conveyor' terms: '' + highway/footway/crossing: + # footway=crossing + name: Pedestrian Crossing highway/footway/marked: # 'footway=crossing, crossing=marked' name: Marked Crosswalk @@ -4260,12 +4269,12 @@ en: # 'terms: pavement,sidepath' terms: '' highway/footway/unmarked: - # footway=crossing + # 'footway=crossing, crossing=unmarked' name: Unmarked Crossing # 'terms: unmarked foot path crossing,unmarked crosswalk,unmarked pedestrian crossing' terms: '' highway/footway/unmarked-raised: - # 'footway=crossing, traffic_calming=table' + # 'footway=crossing, crossing=unmarked, traffic_calming=table' name: Unmarked Crossing (Raised) # 'terms: flat top,hump,speed,slow' terms: '' diff --git a/data/presets/presets.json b/data/presets/presets.json index f653acf30..e3beba1af 100644 --- a/data/presets/presets.json +++ b/data/presets/presets.json @@ -432,6 +432,7 @@ "healthcare/rehabilitation": {"icon": "maki-hospital", "geometry": ["point", "area"], "terms": ["rehab", "therapist", "therapy"], "tags": {"healthcare": "rehabilitation"}, "name": "Rehabilitation Facility"}, "healthcare/speech_therapist": {"icon": "fas-comment", "geometry": ["point", "area"], "terms": ["speech", "therapist", "therapy", "voice"], "tags": {"healthcare": "speech_therapist"}, "name": "Speech Therapist"}, "highway/bus_stop": {"icon": "maki-bus", "fields": ["name", "network", "operator", "bench", "shelter"], "geometry": ["point", "vertex"], "tags": {"highway": "bus_stop"}, "matchScore": 0.95, "name": "Bus Stop", "searchable": false, "replacement": "public_transport/platform/bus_point"}, + "highway/crossing": {"fields": ["crossing"], "geometry": ["vertex"], "tags": {"highway": "crossing"}, "searchable": false, "matchScore": 0.95, "name": "Crossing"}, "highway/bridleway": {"fields": ["name", "surface", "width", "structure", "access", "incline", "horse_scale"], "moreFields": ["covered", "dog", "lit", "maxweight_bridge", "smoothness", "wheelchair"], "icon": "maki-horse-riding", "geometry": ["line"], "tags": {"highway": "bridleway"}, "terms": ["bridleway", "equestrian", "horse", "trail"], "name": "Bridle Path"}, "highway/bus_guideway": {"icon": "maki-bus", "fields": ["name", "operator", "oneway", "structure", "covered"], "moreFields": ["trolley_wire"], "geometry": ["line"], "tags": {"highway": "bus_guideway"}, "addTags": {"highway": "bus_guideway", "access": "no", "bus": "designated"}, "removeTags": {"highway": "bus_guideway", "access": "no", "bus": "designated"}, "terms": [], "name": "Bus Guideway"}, "highway/construction": {"icon": "maki-barrier", "fields": ["name", "opening_date", "check_date", "note", "oneway", "structure", "access"], "geometry": ["line"], "tags": {"highway": "construction", "access": "no"}, "terms": ["closed", "closure", "construction"], "name": "Road Closed"}, @@ -440,22 +441,24 @@ "highway/crossing/zebra": {"icon": "temaki-pedestrian", "fields": ["crossing", "tactile_paving"], "geometry": ["vertex"], "tags": {"highway": "crossing", "crossing": "zebra"}, "reference": {"key": "highway", "value": "crossing"}, "terms": ["zebra crossing", "marked crossing", "crosswalk"], "name": "Marked Crosswalk", "searchable": false}, "highway/crossing/marked-raised": {"icon": "temaki-pedestrian", "fields": ["crossing", "tactile_paving"], "geometry": ["vertex"], "tags": {"crossing": "marked", "traffic_calming": "table"}, "addTags": {"highway": "crossing", "crossing": "marked", "traffic_calming": "table"}, "removeTags": {"highway": "crossing", "crossing": "marked", "traffic_calming": "table"}, "reference": {"key": "traffic_calming", "value": "table"}, "terms": ["zebra crossing", "marked crossing", "crosswalk", "flat top", "hump", "speed", "slow"], "name": "Marked Crosswalk (Raised)"}, "highway/crossing/marked": {"icon": "temaki-pedestrian", "fields": ["crossing", "tactile_paving"], "geometry": ["vertex"], "tags": {"crossing": "marked"}, "addTags": {"highway": "crossing", "crossing": "marked"}, "removeTags": {"highway": "crossing", "crossing": "marked"}, "reference": {"key": "highway", "value": "crossing"}, "terms": ["zebra crossing", "marked crossing", "crosswalk"], "name": "Marked Crosswalk"}, - "highway/crossing/unmarked-raised": {"fields": ["crossing", "tactile_paving"], "geometry": ["vertex"], "addTags": {"highway": "crossing", "crossing": "unmarked", "traffic_calming": "table"}, "removeTags": {"highway": "crossing", "crossing": "unmarked", "traffic_calming": "table"}, "tags": {"highway": "crossing", "traffic_calming": "table"}, "reference": {"key": "traffic_calming", "value": "table"}, "terms": ["flat top", "hump", "speed", "slow"], "matchScore": 0.95, "name": "Unmarked Crossing (Raised)"}, - "highway/crossing/unmarked": {"fields": ["crossing", "tactile_paving"], "geometry": ["vertex"], "addTags": {"highway": "crossing", "crossing": "unmarked"}, "removeTags": {"highway": "crossing", "crossing": "unmarked"}, "tags": {"highway": "crossing"}, "reference": {"key": "highway", "value": "crossing"}, "terms": [], "matchScore": 0.95, "name": "Unmarked Crossing"}, + "highway/crossing/unmarked-raised": {"icon": "temaki-pedestrian", "fields": ["crossing", "tactile_paving"], "geometry": ["vertex"], "tags": {"highway": "crossing", "crossing": "unmarked", "traffic_calming": "table"}, "reference": {"key": "traffic_calming", "value": "table"}, "terms": ["flat top", "hump", "speed", "slow"], "name": "Unmarked Crossing (Raised)"}, + "highway/crossing/unmarked": {"icon": "temaki-pedestrian", "fields": ["crossing", "tactile_paving"], "geometry": ["vertex"], "tags": {"crossing": "unmarked"}, "addTags": {"highway": "crossing", "crossing": "unmarked"}, "removeTags": {"highway": "crossing", "crossing": "unmarked"}, "reference": {"key": "crossing", "value": "unmarked"}, "terms": [], "name": "Unmarked Crossing"}, "highway/cycleway": {"icon": "maki-bicycle", "fields": ["name", "oneway", "surface", "width", "structure", "access", "incline"], "moreFields": ["covered", "dog", "lit", "maxspeed", "maxweight_bridge", "smoothness", "wheelchair"], "geometry": ["line"], "tags": {"highway": "cycleway"}, "terms": ["bike path", "bicyle path"], "matchScore": 0.9, "name": "Cycle Path"}, + "highway/cycleway/crossing": {"icon": "maki-bicycle", "fields": ["crossing", "access", "surface", "tactile_paving"], "geometry": ["line"], "tags": {"cycleway": "crossing"}, "addTags": {"highway": "cycleway", "cycleway": "crossing"}, "removeTags": {"highway": "cycleway", "cycleway": "crossing"}, "reference": {"key": "cycleway", "value": "crossing"}, "searchable": false, "matchScore": 0.95, "name": "Cycle Crossing"}, "highway/cycleway/bicycle_foot": {"icon": "maki-bicycle", "geometry": ["line"], "tags": {"highway": "cycleway", "foot": "designated"}, "addTags": {"highway": "cycleway", "foot": "designated", "bicycle": "designated"}, "removeTags": {"highway": "cycleway", "foot": "designated", "bicycle": "designated"}, "terms": ["bicycle and foot path", "mixed-use trail", "multi-use trail", "segregated trail"], "matchScore": 0.95, "name": "Cycle & Foot Path"}, "highway/cycleway/crossing/marked": {"icon": "maki-bicycle", "fields": ["crossing", "access", "surface", "tactile_paving"], "geometry": ["line"], "tags": {"cycleway": "crossing", "crossing": "marked"}, "addTags": {"highway": "cycleway", "cycleway": "crossing", "crossing": "marked"}, "removeTags": {"highway": "cycleway", "cycleway": "crossing", "crossing": "marked"}, "reference": {"key": "cycleway", "value": "crossing"}, "terms": ["cycle crosswalk", "cycle path crossing", "cycleway crossing", "bicycle crossing", "bike crossing"], "name": "Marked Cycle Crossing"}, - "highway/cycleway/crossing/unmarked": {"icon": "maki-bicycle", "fields": ["crossing", "access", "surface", "tactile_paving"], "geometry": ["line"], "tags": {"cycleway": "crossing"}, "addTags": {"highway": "cycleway", "cycleway": "crossing", "crossing": "unmarked"}, "removeTags": {"highway": "cycleway", "cycleway": "crossing", "crossing": "unmarked"}, "reference": {"key": "cycleway", "value": "crossing"}, "terms": ["cycle path crossing", "cycleway crossing", "bicycle crossing", "bike crossing"], "matchScore": 0.95, "name": "Unmarked Cycle Crossing"}, + "highway/cycleway/crossing/unmarked": {"icon": "maki-bicycle", "fields": ["crossing", "access", "surface", "tactile_paving"], "geometry": ["line"], "tags": {"cycleway": "crossing", "crossing": "unmarked"}, "addTags": {"highway": "cycleway", "cycleway": "crossing", "crossing": "unmarked"}, "removeTags": {"highway": "cycleway", "cycleway": "crossing", "crossing": "unmarked"}, "reference": {"key": "cycleway", "value": "crossing"}, "terms": ["cycle path crossing", "cycleway crossing", "bicycle crossing", "bike crossing"], "name": "Unmarked Cycle Crossing"}, "highway/elevator": {"icon": "temaki-elevator", "fields": ["access_simple", "opening_hours", "maxweight", "ref", "wheelchair"], "moreFields": ["maxheight"], "geometry": ["vertex"], "tags": {"highway": "elevator"}, "terms": ["lift"], "name": "Elevator"}, "highway/footway": {"icon": "temaki-pedestrian", "fields": ["name", "surface", "width", "structure", "access", "incline"], "moreFields": ["covered", "dog", "lit", "maxweight_bridge", "smoothness", "wheelchair"], "geometry": ["line"], "terms": ["hike", "hiking", "promenade", "trackway", "trail", "walk"], "tags": {"highway": "footway"}, "matchScore": 0.9, "name": "Foot Path"}, + "highway/footway/crossing": {"fields": ["crossing", "access", "surface", "tactile_paving"], "geometry": ["line"], "tags": {"footway": "crossing"}, "addTags": {"highway": "footway", "footway": "crossing"}, "removeTags": {"highway": "footway", "footway": "crossing"}, "reference": {"key": "footway", "value": "crossing"}, "matchScore": 0.95, "searchable": false, "name": "Pedestrian Crossing"}, "highway/footway/zebra-raised": {"icon": "temaki-pedestrian", "fields": ["crossing", "access", "surface", "tactile_paving"], "geometry": ["line"], "tags": {"highway": "footway", "footway": "crossing", "crossing": "zebra", "traffic_calming": "table"}, "reference": {"key": "traffic_calming", "value": "table"}, "terms": ["zebra crossing", "marked crossing", "crosswalk", "flat top", "hump", "speed", "slow"], "name": "Marked Crosswalk (Raised)", "searchable": false}, "highway/footway/zebra": {"icon": "temaki-pedestrian", "fields": ["crossing", "access", "surface", "tactile_paving"], "geometry": ["line"], "tags": {"highway": "footway", "footway": "crossing", "crossing": "zebra"}, "reference": {"key": "footway", "value": "crossing"}, "terms": ["zebra crossing", "marked crossing", "crosswalk"], "name": "Marked Crosswalk", "searchable": false}, "highway/footway/conveying": {"icon": "temaki-pedestrian", "fields": ["name", "conveying", "access_simple", "lit", "width", "wheelchair"], "geometry": ["line"], "terms": ["moving sidewalk", "autwalk", "skywalk", "travolator", "travelator", "travellator", "conveyor"], "tags": {"highway": "footway", "conveying": "*"}, "name": "Moving Walkway"}, "highway/footway/marked-raised": {"icon": "temaki-pedestrian", "fields": ["crossing", "access", "surface", "tactile_paving"], "geometry": ["line"], "tags": {"footway": "crossing", "crossing": "marked", "traffic_calming": "table"}, "addTags": {"highway": "footway", "footway": "crossing", "crossing": "marked", "traffic_calming": "table"}, "removeTags": {"highway": "footway", "footway": "crossing", "crossing": "marked", "traffic_calming": "table"}, "reference": {"key": "traffic_calming", "value": "table"}, "terms": ["zebra crossing", "marked crossing", "crosswalk", "flat top", "hump", "speed", "slow"], "name": "Marked Crosswalk (Raised)"}, "highway/footway/marked": {"icon": "temaki-pedestrian", "fields": ["crossing", "access", "surface", "tactile_paving"], "geometry": ["line"], "tags": {"footway": "crossing", "crossing": "marked"}, "addTags": {"highway": "footway", "footway": "crossing", "crossing": "marked"}, "removeTags": {"highway": "footway", "footway": "crossing", "crossing": "marked"}, "reference": {"key": "footway", "value": "crossing"}, "terms": ["marked foot path crossing", "marked crossing", "marked pedestrian crosswalk", "zebra crossing"], "name": "Marked Crosswalk"}, "highway/footway/sidewalk": {"icon": "temaki-pedestrian", "geometry": ["line"], "tags": {"footway": "sidewalk"}, "addTags": {"highway": "footway", "footway": "sidewalk"}, "removeTags": {"highway": "footway", "footway": "sidewalk"}, "reference": {"key": "footway", "value": "sidewalk"}, "terms": ["pavement", "sidepath"], "name": "Sidewalk"}, - "highway/footway/unmarked-raised": {"fields": ["crossing", "access", "surface", "tactile_paving"], "geometry": ["line"], "tags": {"footway": "crossing", "traffic_calming": "table"}, "addTags": {"highway": "footway", "footway": "crossing", "crossing": "unmarked", "traffic_calming": "table"}, "removeTags": {"highway": "footway", "footway": "crossing", "crossing": "unmarked", "traffic_calming": "table"}, "reference": {"key": "traffic_calming", "value": "table"}, "terms": ["flat top", "hump", "speed", "slow"], "matchScore": 0.95, "name": "Unmarked Crossing (Raised)"}, - "highway/footway/unmarked": {"fields": ["crossing", "access", "surface", "tactile_paving"], "geometry": ["line"], "tags": {"footway": "crossing"}, "addTags": {"highway": "footway", "footway": "crossing", "crossing": "unmarked"}, "removeTags": {"highway": "footway", "footway": "crossing", "crossing": "unmarked"}, "reference": {"key": "footway", "value": "crossing"}, "terms": ["unmarked foot path crossing", "unmarked crosswalk", "unmarked pedestrian crossing"], "matchScore": 0.95, "name": "Unmarked Crossing"}, + "highway/footway/unmarked-raised": {"icon": "temaki-pedestrian", "fields": ["crossing", "access", "surface", "tactile_paving"], "geometry": ["line"], "tags": {"footway": "crossing", "crossing": "unmarked", "traffic_calming": "table"}, "addTags": {"highway": "footway", "footway": "crossing", "crossing": "unmarked", "traffic_calming": "table"}, "removeTags": {"highway": "footway", "footway": "crossing", "crossing": "unmarked", "traffic_calming": "table"}, "reference": {"key": "traffic_calming", "value": "table"}, "terms": ["flat top", "hump", "speed", "slow"], "name": "Unmarked Crossing (Raised)"}, + "highway/footway/unmarked": {"icon": "temaki-pedestrian", "fields": ["crossing", "access", "surface", "tactile_paving"], "geometry": ["line"], "tags": {"footway": "crossing", "crossing": "unmarked"}, "addTags": {"highway": "footway", "footway": "crossing", "crossing": "unmarked"}, "removeTags": {"highway": "footway", "footway": "crossing", "crossing": "unmarked"}, "reference": {"key": "footway", "value": "crossing"}, "terms": ["unmarked foot path crossing", "unmarked crosswalk", "unmarked pedestrian crossing"], "name": "Unmarked Crossing"}, "highway/give_way": {"icon": "temaki-yield", "fields": ["direction_vertex"], "geometry": ["vertex"], "tags": {"highway": "give_way"}, "terms": ["give way", "yield", "sign"], "name": "Yield Sign"}, "highway/living_street": {"icon": "iD-highway-living-street", "fields": ["name", "oneway", "maxspeed", "lanes", "surface", "structure", "access"], "moreFields": ["covered", "cycleway", "flood_prone", "junction_line", "lit", "maxheight", "maxweight_bridge", "oneway/bicycle", "smoothness", "trolley_wire"], "geometry": ["line"], "tags": {"highway": "living_street"}, "name": "Living Street"}, "highway/milestone": {"icon": "temaki-milestone", "geometry": ["point", "vertex"], "fields": ["distance", "direction_vertex"], "tags": {"highway": "milestone"}, "terms": ["mile marker", "mile post", "mile stone", "mileage marker", "milemarker", "milepost"], "name": "Highway Milestone"}, diff --git a/data/presets/presets/highway/_crossing.json b/data/presets/presets/highway/_crossing.json new file mode 100644 index 000000000..8be3c3c5c --- /dev/null +++ b/data/presets/presets/highway/_crossing.json @@ -0,0 +1,14 @@ +{ + "fields": [ + "crossing" + ], + "geometry": [ + "vertex" + ], + "tags": { + "highway": "crossing" + }, + "searchable": false, + "matchScore": 0.95, + "name": "Crossing" +} diff --git a/data/presets/presets/highway/crossing/unmarked-raised.json b/data/presets/presets/highway/crossing/unmarked-raised.json index 19868796f..a3149ee0a 100644 --- a/data/presets/presets/highway/crossing/unmarked-raised.json +++ b/data/presets/presets/highway/crossing/unmarked-raised.json @@ -1,4 +1,5 @@ { + "icon": "temaki-pedestrian", "fields": [ "crossing", "tactile_paving" @@ -6,18 +7,9 @@ "geometry": [ "vertex" ], - "addTags": { - "highway": "crossing", - "crossing": "unmarked", - "traffic_calming": "table" - }, - "removeTags": { - "highway": "crossing", - "crossing": "unmarked", - "traffic_calming": "table" - }, "tags": { "highway": "crossing", + "crossing": "unmarked", "traffic_calming": "table" }, "reference": { @@ -30,6 +22,5 @@ "speed", "slow" ], - "matchScore": 0.95, "name": "Unmarked Crossing (Raised)" } diff --git a/data/presets/presets/highway/crossing/unmarked.json b/data/presets/presets/highway/crossing/unmarked.json index a29e0ab9e..f99a66c9d 100644 --- a/data/presets/presets/highway/crossing/unmarked.json +++ b/data/presets/presets/highway/crossing/unmarked.json @@ -1,4 +1,5 @@ { + "icon": "temaki-pedestrian", "fields": [ "crossing", "tactile_paving" @@ -6,6 +7,9 @@ "geometry": [ "vertex" ], + "tags": { + "crossing": "unmarked" + }, "addTags": { "highway": "crossing", "crossing": "unmarked" @@ -14,14 +18,10 @@ "highway": "crossing", "crossing": "unmarked" }, - "tags": { - "highway": "crossing" - }, "reference": { - "key": "highway", - "value": "crossing" + "key": "crossing", + "value": "unmarked" }, "terms": [], - "matchScore": 0.95, "name": "Unmarked Crossing" } diff --git a/data/presets/presets/highway/cycleway/_crossing.json b/data/presets/presets/highway/cycleway/_crossing.json new file mode 100644 index 000000000..51a594d4f --- /dev/null +++ b/data/presets/presets/highway/cycleway/_crossing.json @@ -0,0 +1,30 @@ +{ + "icon": "maki-bicycle", + "fields": [ + "crossing", + "access", + "surface", + "tactile_paving" + ], + "geometry": [ + "line" + ], + "tags": { + "cycleway": "crossing" + }, + "addTags": { + "highway": "cycleway", + "cycleway": "crossing" + }, + "removeTags": { + "highway": "cycleway", + "cycleway": "crossing" + }, + "reference": { + "key": "cycleway", + "value": "crossing" + }, + "searchable": false, + "matchScore": 0.95, + "name": "Cycle Crossing" +} diff --git a/data/presets/presets/highway/cycleway/crossing/unmarked.json b/data/presets/presets/highway/cycleway/crossing/unmarked.json index 33c626bb7..a91bf05e4 100644 --- a/data/presets/presets/highway/cycleway/crossing/unmarked.json +++ b/data/presets/presets/highway/cycleway/crossing/unmarked.json @@ -10,7 +10,8 @@ "line" ], "tags": { - "cycleway": "crossing" + "cycleway": "crossing", + "crossing": "unmarked" }, "addTags": { "highway": "cycleway", @@ -32,6 +33,5 @@ "bicycle crossing", "bike crossing" ], - "matchScore": 0.95, "name": "Unmarked Cycle Crossing" } diff --git a/data/presets/presets/highway/footway/_crossing.json b/data/presets/presets/highway/footway/_crossing.json new file mode 100644 index 000000000..57e02af21 --- /dev/null +++ b/data/presets/presets/highway/footway/_crossing.json @@ -0,0 +1,29 @@ +{ + "fields": [ + "crossing", + "access", + "surface", + "tactile_paving" + ], + "geometry": [ + "line" + ], + "tags": { + "footway": "crossing" + }, + "addTags": { + "highway": "footway", + "footway": "crossing" + }, + "removeTags": { + "highway": "footway", + "footway": "crossing" + }, + "reference": { + "key": "footway", + "value": "crossing" + }, + "matchScore": 0.95, + "searchable": false, + "name": "Pedestrian Crossing" +} diff --git a/data/presets/presets/highway/footway/unmarked-raised.json b/data/presets/presets/highway/footway/unmarked-raised.json index 90ab9901f..c1fe28bed 100644 --- a/data/presets/presets/highway/footway/unmarked-raised.json +++ b/data/presets/presets/highway/footway/unmarked-raised.json @@ -1,4 +1,5 @@ { + "icon": "temaki-pedestrian", "fields": [ "crossing", "access", @@ -10,6 +11,7 @@ ], "tags": { "footway": "crossing", + "crossing": "unmarked", "traffic_calming": "table" }, "addTags": { @@ -34,6 +36,5 @@ "speed", "slow" ], - "matchScore": 0.95, "name": "Unmarked Crossing (Raised)" } diff --git a/data/presets/presets/highway/footway/unmarked.json b/data/presets/presets/highway/footway/unmarked.json index 3f1efbdb2..49c031fad 100644 --- a/data/presets/presets/highway/footway/unmarked.json +++ b/data/presets/presets/highway/footway/unmarked.json @@ -1,4 +1,5 @@ { + "icon": "temaki-pedestrian", "fields": [ "crossing", "access", @@ -9,7 +10,8 @@ "line" ], "tags": { - "footway": "crossing" + "footway": "crossing", + "crossing": "unmarked" }, "addTags": { "highway": "footway", @@ -30,6 +32,5 @@ "unmarked crosswalk", "unmarked pedestrian crossing" ], - "matchScore": 0.95, "name": "Unmarked Crossing" } diff --git a/data/taginfo.json b/data/taginfo.json index 67796f9ce..513ee8ad6 100644 --- a/data/taginfo.json +++ b/data/taginfo.json @@ -424,6 +424,7 @@ {"key": "healthcare", "value": "rehabilitation", "description": "🄿 Rehabilitation Facility", "object_types": ["node", "area"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/hospital-15.svg?sanitize=true"}, {"key": "healthcare", "value": "speech_therapist", "description": "🄿 Speech Therapist", "object_types": ["node", "area"], "icon_url": "https://raw.githubusercontent.com/openstreetmap/iD/master/svg/fontawesome/fas-comment.svg?sanitize=true"}, {"key": "highway", "value": "bus_stop", "description": "🄿 Bus Stop (unsearchable)", "object_types": ["node"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/bus-15.svg?sanitize=true"}, + {"key": "highway", "value": "crossing", "description": "🄿 Crossing (unsearchable)", "object_types": ["node"]}, {"key": "highway", "value": "bridleway", "description": "🄿 Bridle Path", "object_types": ["way"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/horse-riding-15.svg?sanitize=true"}, {"key": "highway", "value": "bus_guideway", "description": "🄿 Bus Guideway", "object_types": ["way"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/bus-15.svg?sanitize=true"}, {"key": "access", "value": "no", "description": "🄿 Road Closed, 🄵 Allowed Access", "object_types": ["way"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/barrier-15.svg?sanitize=true"}, @@ -431,15 +432,15 @@ {"key": "traffic_calming", "value": "table", "description": "🄿 Marked Crosswalk (Raised) (unsearchable), 🄿 Marked Crosswalk (Raised), 🄿 Unmarked Crossing (Raised), 🄿 Speed Table", "object_types": ["node"], "icon_url": "https://raw.githubusercontent.com/bhousel/temaki/master/icons/pedestrian.svg?sanitize=true"}, {"key": "crossing", "value": "zebra", "description": "🄿 Marked Crosswalk (unsearchable), 🄳 ➜ crossing=marked", "object_types": ["node"], "icon_url": "https://raw.githubusercontent.com/bhousel/temaki/master/icons/pedestrian.svg?sanitize=true"}, {"key": "crossing", "value": "marked", "description": "🄿 Marked Crosswalk, 🄿 Marked Cycle Crossing", "object_types": ["node"], "icon_url": "https://raw.githubusercontent.com/bhousel/temaki/master/icons/pedestrian.svg?sanitize=true"}, - {"key": "highway", "value": "crossing", "description": "🄿 Unmarked Crossing", "object_types": ["node"]}, + {"key": "crossing", "value": "unmarked", "description": "🄿 Unmarked Crossing, 🄿 Unmarked Cycle Crossing", "object_types": ["node"], "icon_url": "https://raw.githubusercontent.com/bhousel/temaki/master/icons/pedestrian.svg?sanitize=true"}, {"key": "highway", "value": "cycleway", "description": "🄿 Cycle Path", "object_types": ["way"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/bicycle-15.svg?sanitize=true"}, + {"key": "cycleway", "value": "crossing", "description": "🄿 Cycle Crossing (unsearchable)", "object_types": ["way"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/bicycle-15.svg?sanitize=true"}, {"key": "foot", "value": "designated", "description": "🄿 Cycle & Foot Path, 🄵 Allowed Access", "object_types": ["way"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/bicycle-15.svg?sanitize=true"}, - {"key": "cycleway", "value": "crossing", "description": "🄿 Unmarked Cycle Crossing", "object_types": ["way"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/bicycle-15.svg?sanitize=true"}, {"key": "highway", "value": "elevator", "description": "🄿 Elevator", "object_types": ["node"], "icon_url": "https://raw.githubusercontent.com/bhousel/temaki/master/icons/elevator.svg?sanitize=true"}, {"key": "highway", "value": "footway", "description": "🄿 Foot Path", "object_types": ["way"], "icon_url": "https://raw.githubusercontent.com/bhousel/temaki/master/icons/pedestrian.svg?sanitize=true"}, + {"key": "footway", "value": "crossing", "description": "🄿 Pedestrian Crossing (unsearchable)", "object_types": ["way"]}, {"key": "conveying", "description": "🄿 Moving Walkway, 🄿 Escalator", "object_types": ["way"], "icon_url": "https://raw.githubusercontent.com/bhousel/temaki/master/icons/pedestrian.svg?sanitize=true"}, {"key": "footway", "value": "sidewalk", "description": "🄿 Sidewalk", "object_types": ["way"], "icon_url": "https://raw.githubusercontent.com/bhousel/temaki/master/icons/pedestrian.svg?sanitize=true"}, - {"key": "footway", "value": "crossing", "description": "🄿 Unmarked Crossing", "object_types": ["way"]}, {"key": "highway", "value": "give_way", "description": "🄿 Yield Sign", "object_types": ["node"], "icon_url": "https://raw.githubusercontent.com/bhousel/temaki/master/icons/yield.svg?sanitize=true"}, {"key": "highway", "value": "living_street", "description": "🄿 Living Street", "object_types": ["way"], "icon_url": "https://raw.githubusercontent.com/openstreetmap/iD/master/svg/iD-sprite/presets/highway-living-street.svg?sanitize=true"}, {"key": "highway", "value": "milestone", "description": "🄿 Highway Milestone", "object_types": ["node"], "icon_url": "https://raw.githubusercontent.com/bhousel/temaki/master/icons/milestone.svg?sanitize=true"}, diff --git a/dist/locales/en.json b/dist/locales/en.json index fe721da02..990331031 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -1604,6 +1604,13 @@ "reference": "Intersecting highways should share a junction vertex." } }, + "close_nodes": { + "title": "Very Close Points", + "message": "Two points in {way} are very close together", + "tip": "Find redundant points in ways", + "ref_merge": "Nodes are less than 2 meters away; you may want to merge them.", + "ref_move_away": "Nodes are less than 2 meters away but not mergable; you may want to move them further apart." + }, "crossing_ways": { "title": "Crossings Ways", "message": "{feature} crosses {feature2}", @@ -1748,7 +1755,7 @@ "end": { "message": "{feature} flows against a connected waterway" }, - "reference": "Waterway segements should all flow in the same direction." + "reference": "Waterway segments should all flow in the same direction." } }, "highway": { @@ -1796,6 +1803,9 @@ "ignore_issue": { "title": "Ignore this issue" }, + "merge_points": { + "title": "Merge these points" + }, "move_tags": { "title": "Move the tags", "annotation": "Moved tags." @@ -5955,6 +5965,10 @@ "name": "Bus Stop", "terms": "" }, + "highway/crossing": { + "name": "Crossing", + "terms": "" + }, "highway/bridleway": { "name": "Bridle Path", "terms": "bridleway,equestrian,horse,trail" @@ -5999,6 +6013,10 @@ "name": "Cycle Path", "terms": "bike path,bicyle path" }, + "highway/cycleway/crossing": { + "name": "Cycle Crossing", + "terms": "" + }, "highway/cycleway/bicycle_foot": { "name": "Cycle & Foot Path", "terms": "bicycle and foot path,mixed-use trail,multi-use trail,segregated trail" @@ -6019,6 +6037,10 @@ "name": "Foot Path", "terms": "hike,hiking,promenade,trackway,trail,walk" }, + "highway/footway/crossing": { + "name": "Pedestrian Crossing", + "terms": "" + }, "highway/footway/zebra-raised": { "name": "Marked Crosswalk (Raised)", "terms": "zebra crossing,marked crossing,crosswalk,flat top,hump,speed,slow" diff --git a/modules/actions/connect.js b/modules/actions/connect.js index 47a1b3742..581766245 100644 --- a/modules/actions/connect.js +++ b/modules/actions/connect.js @@ -80,7 +80,7 @@ export function actionConnect(nodeIDs) { role = relation.memberById(node.id).role || ''; // if this node is a via node in a restriction, remember for later - if (relation.isValidRestriction()) { + if (relation.hasFromViaTo()) { restrictionIDs.push(relation.id); } @@ -103,7 +103,7 @@ export function actionConnect(nodeIDs) { for (k = 0; k < relations.length; k++) { relation = relations[k]; - if (relation.isValidRestriction()) { + if (relation.hasFromViaTo()) { restrictionIDs.push(relation.id); } } diff --git a/modules/actions/extract.js b/modules/actions/extract.js index 6bbd45850..e9f8409bc 100644 --- a/modules/actions/extract.js +++ b/modules/actions/extract.js @@ -98,7 +98,7 @@ export function actionExtract(entityID, projection) { var parentRels = graph.parentRelations(entity); for (var i = 0; i < parentRels.length; i++) { var relation = parentRels[i]; - if (!relation.isValidRestriction()) continue; + if (!relation.hasFromViaTo()) continue; for (var j = 0; j < relation.members.length; j++) { var m = relation.members[j]; diff --git a/modules/actions/reverse.js b/modules/actions/reverse.js index fc0d6faa3..a560abbc0 100644 --- a/modules/actions/reverse.js +++ b/modules/actions/reverse.js @@ -25,7 +25,11 @@ export function actionReverse(wayID, options) { [/:right$/, ':left'], [/:left$/, ':right'], [/:forward$/, ':backward'], - [/:backward$/, ':forward'] + [/:backward$/, ':forward'], + [/:right:/, ':left:'], + [/:left:/, ':right:'], + [/:forward:/, ':backward:'], + [/:backward:/, ':forward:'] ]; var valueReplacements = { left: 'right', diff --git a/modules/actions/split.js b/modules/actions/split.js index 7f78a6bd5..ac1c1f86f 100644 --- a/modules/actions/split.js +++ b/modules/actions/split.js @@ -118,7 +118,7 @@ export function actionSplit(nodeId, newWayIds) { // 1. Splitting a FROM/TO way - only `wayA` OR `wayB` remains in relation // (whichever one is connected to the VIA node/ways) // 2. Splitting a VIA way - `wayB` remains in relation as a VIA way - if (relation.isRestriction()) { + if (relation.hasFromViaTo()) { var f = relation.memberByRole('from'); var v = relation.membersByRole('via'); var t = relation.memberByRole('to'); diff --git a/modules/osm/relation.js b/modules/osm/relation.js index a02f761d6..a01ee2342 100644 --- a/modules/osm/relation.js +++ b/modules/osm/relation.js @@ -256,6 +256,15 @@ Object.assign(osmRelation.prototype, { }, + hasFromViaTo: function() { + return ( + this.members.some(function(m) { return m.role === 'from'; }) && + this.members.some(function(m) { return m.role === 'via'; }) && + this.members.some(function(m) { return m.role === 'to'; }) + ); + }, + + isRestriction: function() { return !!(this.tags.type && this.tags.type.match(/^restriction:?/)); }, diff --git a/modules/ui/fields/wikipedia.js b/modules/ui/fields/wikipedia.js index d985d7de1..8b50c1b98 100644 --- a/modules/ui/fields/wikipedia.js +++ b/modules/ui/fields/wikipedia.js @@ -168,12 +168,13 @@ export function uiFieldWikipedia(field, context) { value = decodeURIComponent(m[2]).replace(/_/g, ' '); if (m[3]) { var anchor; - try { + // try { + // leave this out for now - #6232 // Best-effort `anchordecode:` implementation - anchor = decodeURIComponent(m[3].replace(/\.([0-9A-F]{2})/g, '%$1')); - } catch (e) { + // anchor = decodeURIComponent(m[3].replace(/\.([0-9A-F]{2})/g, '%$1')); + // } catch (e) { anchor = decodeURIComponent(m[3]); - } + // } value += '#' + anchor.replace(/_/g, ' '); } value = value.slice(0, 1).toUpperCase() + value.slice(1); diff --git a/modules/ui/inspector.js b/modules/ui/inspector.js index 264b45380..bce4f9479 100644 --- a/modules/ui/inspector.js +++ b/modules/ui/inspector.js @@ -52,8 +52,9 @@ export function uiInspector(context) { var hasNonGeometryTags = entity.hasNonGeometryTags(); var isTaglessOrIntersectionVertex = entity.geometry(context.graph()) === 'vertex' && (!hasNonGeometryTags && !entity.isHighwayIntersection(context.graph())); + var issues = context.validator().getEntityIssues(_entityID); // start with the preset list if the feature is new and untagged or is an uninteresting vertex - var showPresetList = (newFeature && !hasNonGeometryTags) || isTaglessOrIntersectionVertex; + var showPresetList = (newFeature && !hasNonGeometryTags) || (isTaglessOrIntersectionVertex && !issues.length); if (showPresetList) { wrap.style('right', '-100%'); diff --git a/modules/ui/tools/save.js b/modules/ui/tools/save.js index 16a0caee2..ca6473fbe 100644 --- a/modules/ui/tools/save.js +++ b/modules/ui/tools/save.js @@ -104,11 +104,7 @@ export function uiToolSave(context) { context.history() - .on('change.save', function(diff) { - if (!diff || diff.didChange.addition || diff.didChange.deletion) { - updateCount(); // only on significant changes - } - }); + .on('change.save', updateCount); context .on('enter.save', function() { diff --git a/modules/validations/close_nodes.js b/modules/validations/close_nodes.js new file mode 100644 index 000000000..0c36a8235 --- /dev/null +++ b/modules/validations/close_nodes.js @@ -0,0 +1,99 @@ +import { operationMerge } from '../operations/index'; +import { utilDisplayLabel } from '../util'; +import { t } from '../util/locale'; +import { validationIssue, validationIssueFix } from '../core/validation'; +import { osmRoutableHighwayTagValues } from '../osm/tags'; +import { geoExtent } from '../geo'; + + +export function validationCloseNodes() { + var type = 'close_nodes'; + + + function isNodeOnRoad(node, context) { + var parentWays = context.graph().parentWays(node); + for (var i = 0; i < parentWays.length; i++) { + var parentWay = parentWays[i]; + if (osmRoutableHighwayTagValues[parentWay.tags.highway]) { + return parentWay; + } + } + return false; + } + + function findDupeNode(node, context) { + var epsilon = 2e-5, + extent = geoExtent([ + [node.loc[0] - epsilon, node.loc[1] - epsilon], + [node.loc[0] + epsilon, node.loc[1] + epsilon] + ]); + var filteredEnts = context.intersects(extent); + for (var i = 0; i < filteredEnts.length; i++) { + var entity = filteredEnts[i]; + if (entity.type === 'node' && entity.id !== node.id && + Math.abs(node.loc[0] - entity.loc[0]) < epsilon && + Math.abs(node.loc[1] - entity.loc[1]) < epsilon && + isNodeOnRoad(entity, context) ) { + return entity; + } + } + return null; + } + + + var validation = function(entity, context) { + + if (entity.type !== 'node') return []; + + var road = isNodeOnRoad(entity, context); + if (!road) return []; + + var dupe = findDupeNode(entity, context); + if (dupe === null) return []; + + var mergable = !operationMerge([entity.id, dupe.id], context).disabled(); + var fixes = []; + if (mergable) { + fixes.push( + new validationIssueFix({ + icon: 'iD-icon-plus', + title: t('issues.fix.merge_points.title'), + onClick: function() { + var entityIds = this.issue.entityIds, + operation = operationMerge([entityIds[0], entityIds[1]], context); + if (!operation.disabled()) { + operation(); + } + } + }) + ); + } + + return [new validationIssue({ + type: type, + severity: 'warning', + message: t('issues.close_nodes.message', { way: utilDisplayLabel(road, context) }), + reference: showReference, + entityIds: [entity.id, dupe.id], + fixes: fixes + })]; + + + function showReference(selection) { + var referenceText = mergable + ? t('issues.close_nodes.ref_merge') + : t('issues.close_nodes.ref_move_away'); + selection.selectAll('.issue-reference') + .data([0]) + .enter() + .append('div') + .attr('class', 'issue-reference') + .text(referenceText); + } + }; + + + validation.type = type; + + return validation; +} diff --git a/modules/validations/crossing_ways.js b/modules/validations/crossing_ways.js index 5e305058e..f36edd9bd 100644 --- a/modules/validations/crossing_ways.js +++ b/modules/validations/crossing_ways.js @@ -164,14 +164,12 @@ export function validationCrossingWays() { return {}; } var pathFeature = entity1IsPath ? entity1 : entity2; - if (pathFeature.tags.highway === 'footway' && - pathFeature.tags.footway === 'crossing' && - ['marked', 'unmarked'].indexOf(pathFeature.tags.crossing) !== -1) { + if (['marked', 'unmarked'].indexOf(pathFeature.tags.crossing) !== -1) { // if the path is a crossing, match the crossing type return { highway: 'crossing', crossing: pathFeature.tags.crossing }; } - // default ambiguous crossings to unmarked - return { highway: 'crossing', crossing: 'unmarked' }; + // don't add a `crossing` subtag to ambiguous crossings + return { highway: 'crossing' }; } return {}; } diff --git a/modules/validations/index.js b/modules/validations/index.js index 35862a874..cecaafeb5 100644 --- a/modules/validations/index.js +++ b/modules/validations/index.js @@ -1,4 +1,5 @@ export { validationAlmostJunction } from './almost_junction'; +export { validationCloseNodes } from './close_nodes'; export { validationCrossingWays } from './crossing_ways'; export { validationDisconnectedWay } from './disconnected_way'; export { validationFixmeTag } from './fixme_tag'; diff --git a/test/spec/actions/reverse.js b/test/spec/actions/reverse.js index df1fd5ea9..6ed6ca10c 100644 --- a/test/spec/actions/reverse.js +++ b/test/spec/actions/reverse.js @@ -103,6 +103,17 @@ describe('iD.actionReverse', function () { expect(graph.entity(way.id).tags).to.eql({'cycleway:right': 'lane'}); }); + it('transforms *:right:*=* ⟺ *:left:*=*', function () { + var way = iD.osmWay({tags: {'cycleway:right:surface': 'paved'}}); + var graph = iD.coreGraph([way]); + + graph = iD.actionReverse(way.id)(graph); + expect(graph.entity(way.id).tags).to.eql({'cycleway:left:surface': 'paved'}); + + graph = iD.actionReverse(way.id)(graph); + expect(graph.entity(way.id).tags).to.eql({'cycleway:right:surface': 'paved'}); + }); + it('transforms *:forward=* ⟺ *:backward=*', function () { var way = iD.osmWay({tags: {'maxspeed:forward': '25'}}); var graph = iD.coreGraph([way]); diff --git a/test/spec/actions/split.js b/test/spec/actions/split.js index 9b6bb7e48..d37fe81de 100644 --- a/test/spec/actions/split.js +++ b/test/spec/actions/split.js @@ -1160,7 +1160,7 @@ describe('iD.actionSplit', function () { }); - ['restriction', 'restriction:bus'].forEach(function (type) { + ['restriction', 'restriction:bus', 'manoeuvre'].forEach(function (type) { describe('type = ' + type, function () { it('updates a restriction\'s \'from\' role - via node', function () { diff --git a/test/spec/osm/relation.js b/test/spec/osm/relation.js index 17fcc222c..e0810eef6 100644 --- a/test/spec/osm/relation.js +++ b/test/spec/osm/relation.js @@ -185,6 +185,85 @@ describe('iD.osmRelation', function () { }); }); + describe('#hasFromViaTo', function () { + it('returns true if there is a from, via, and to', function () { + var r = iD.osmRelation({ + id: 'r', + tags: { type: 'manoeuvre' }, + members: [ + { role: 'from', id: 'f', type: 'way' }, + { role: 'via', id: 'v', type: 'node' }, + { role: 'to', id: 't', type: 'way' } + ] + }); + expect(r.hasFromViaTo()).to.be.true; + }); + + it('returns true if there are extra froms, vias, tos', function () { + var r = iD.osmRelation({ + id: 'r', + tags: { type: 'manoeuvre' }, + members: [ + { role: 'from', id: 'f1', type: 'way' }, + { role: 'from', id: 'f2', type: 'way' }, + { role: 'via', id: 'v1', type: 'node' }, + { role: 'via', id: 'v2', type: 'node' }, + { role: 'to', id: 't1', type: 'way' }, + { role: 'to', id: 't2', type: 'way' } + ] + }); + expect(r.hasFromViaTo()).to.be.true; + }); + + it('returns false if from missing', function () { + var r = iD.osmRelation({ + id: 'r', + tags: { type: 'manoeuvre' }, + members: [ + { role: 'via', id: 'v', type: 'node' }, + { role: 'to', id: 't', type: 'way' } + ] + }); + expect(r.hasFromViaTo()).to.be.false; + }); + + it('returns false if via missing', function () { + var r = iD.osmRelation({ + id: 'r', + tags: { type: 'manoeuvre' }, + members: [ + { role: 'from', id: 'f', type: 'way' }, + { role: 'to', id: 't', type: 'way' } + ] + }); + expect(r.hasFromViaTo()).to.be.false; + }); + + it('returns false if to missing', function () { + var r = iD.osmRelation({ + id: 'r', + tags: { type: 'manoeuvre' }, + members: [ + { role: 'from', id: 'f', type: 'way' }, + { role: 'via', id: 'v', type: 'node' } + ] + }); + expect(r.hasFromViaTo()).to.be.false; + }); + + it('returns false if all missing', function () { + var r = iD.osmRelation({ + id: 'r', + tags: { type: 'multipolygon' }, + members: [ + { role: 'inner', id: 'i', type: 'way' }, + { role: 'outer', id: 'o', type: 'way' } + ] + }); + expect(r.hasFromViaTo()).to.be.false; + }); + }); + describe('#isRestriction', function () { it('returns true for \'restriction\' type', function () { expect(iD.osmRelation({tags: {type: 'restriction'}}).isRestriction()).to.be.true; diff --git a/test/spec/services/mapillary.js b/test/spec/services/mapillary.js index 03d741d83..c74705e19 100644 --- a/test/spec/services/mapillary.js +++ b/test/spec/services/mapillary.js @@ -100,6 +100,7 @@ describe('iD.serviceMapillary', function() { }); it('loads multiple pages of image results', function(done) { + this.timeout(10000); var calls = 0; mapillary.on('loadedImages', function() { server.respond(); // respond to new fetches @@ -193,6 +194,7 @@ describe('iD.serviceMapillary', function() { }); it('loads multiple pages of signs results', function(done) { + this.timeout(10000); var calls = 0; mapillary.on('loadedSigns', function() { server.respond(); // respond to new fetches