def get_left_hand_bicycle(tags, level, country_iso3): sidewalk_use = tags.get('sidewalk:bicycle') == 'yes' or tags.get( 'sidewalk:left:bicycle') == 'yes' or tags.get( 'sidewalk:right:bicycle') == 'yes' or tags.get( 'sidewalk:both:bicycle') == 'yes' or tags.get('sidewalk') in [ 'both', 'right', 'left', 'yes' ] general = tags.get('highway') == 'cycleway' general_oneway = general and tags.get('oneway') == 'yes' # ––––––––––––––––– BIDIRECTIONNAL ––––––––––––––––– # no need to add a new special highway # bike is TRUE # safety = 2 rl1a = ('highway' in tags and tags.get('cycleway') == 'lane') or ( 'highway' in tags and tags.get('cycleway:left') == 'lane' and tags.get('cycleway:right') == 'lane') or (tags.get('cycleway:both') == 'lane') rl1b = 'highway' in tags and tags.get( 'cycleway:right') == 'lane' and tags.get('cycleway:right:oneway') in [ 'false', 'no', 'none', '0' ] rl2 = 'highway' in tags and tags.get('cycleway:right') == 'lane' # ––––––––––––––––– ONE–DIRECTIONNAL LANES––––––––––––––––– rm1 = ('highway' in tags and tags.get('oneway') == 'yes' and tags.get('cycleway') == 'lane' and tags.get('oneway:bicycle') == 'no') or ('highway' in tags and tags.get('oneway') == 'yes' and tags.get('cycleway:left') == 'opposite_lane' and tags.get('cycleway:right') == 'lane') rm2a = ('highway' in tags and tags.get('oneway') == 'yes' and tags.get('cycleway:right') == 'lane') or ('highway' in tags and tags.get('oneway') == 'yes' and tags.get('cycleway') == 'lane') rm2b = ('highway' in tags and tags.get('oneway') == 'yes' and tags.get('cycleway:left') == 'lane') or ('highway' in tags and tags.get('oneway') == 'yes' and tags.get('cycleway') == 'lane') rm2c = 'highway' in tags and tags.get('oneway') == 'yes' and tags.get( 'cycleway') == 'lane' and tags.get('lanes') == '2' rm2d = 'highway' in tags and tags.get('oneway') == 'yes' and tags.get( 'oneway:bicycle') == 'no' and tags.get( 'cycleway:left') == 'lane' and tags.get( 'cycleway:left:oneway') == 'no' rm3a = ('highway' in tags and tags.get('oneway') == 'yes' and tags.get('oneway:bicycle') == 'no' and tags.get('cycleway:left') == 'opposite_lane') or ( 'highway' in tags and tags.get('oneway') == 'yes' and tags.get('oneway:bicycle') == 'no' and tags.get('cycleway') == 'opposite_lane') rm3b = ('highway' in tags and tags.get('oneway') == 'yes' and tags.get('oneway:bicycle') == 'no' and tags.get('cycleway:right') == 'opposite_lane') or ( 'highway' in tags and tags.get('oneway') == 'yes' and tags.get('oneway:bicycle') == 'no' and tags.get('cycleway') == 'opposite_lane') # ––––––––––––––––– ONE–DIRECTIONNAL TRACKS––––––––––––––––– rt1 = 'highway' in tags and tags.get('cycleway') == 'track' rt2 = 'highway' in tags and tags.get( 'cycleway:right') == 'track' and tags.get( 'cycleway:right:oneway') == 'no' rt3 = 'highway' in tags and tags.get('oneway') == 'yes' and tags.get( 'cycleway:right') == 'track' and tags.get('oneway:bicycle') == 'no' rt4 = 'highway' in tags and tags.get('cycleway:right') == 'track' # ––––––––––––––––– SPECIAL ––––––––––––––––– rs1 = ('highway' in tags and tags.get('oneway') == 'yes' and tags.get('oneway:bicycle') == 'no') or ('highway' in tags and tags.get('oneway') == 'yes' and tags.get('cycleway') == 'opposite') rs2 = 'highway' in tags and tags.get( 'cycleway:right') == 'lane' and tags.get('cycleway:left') == 'track' rs3 = 'highway' in tags and tags.get('cycleway') == 'track' and tags.get( 'segregated') == 'yes' rs5 = tags.get('highway') == 'path' and tags.get( 'segregated') == 'yes' and tags.get( 'foot') == 'designated' and tags.get('bicycle') == 'designated' # ––––––––––––––––– CYCLE AND BUS ––––––––––––––––– if tags.get('bicycle:lanes') is not None: rb1 = 'highway' in tags and 'designated' in tags.get( 'bicycle:lanes').split('|') else: rb1 = False rb3 = 'highway' in tags and tags.get( 'cycleway:left') == 'lane' and tags.get( 'cycleway:right') == 'share_busway' rb4 = tags.get('highway') == 'service' and tags.get( 'service') == 'bus' and tags.get('oneway') == 'yes' and tags.get( 'cycleway:right') == 'share_busway' rb5 = 'highway' in tags and tags.get( 'busway:right') == 'lane' and tags.get( 'cycleway:right') == 'share_busway' rb6 = ('highway' in tags and tags.get('cycleway:left') == 'share_busway' and tags.get('busway') == 'opposite_lane' and tags.get('oneway') == 'yes' and tags.get('oneway:bicycle') == 'no') or ('highway' in tags and tags.get('cycleway:left') == 'share_busway' and tags.get('busway') == 'lane' and tags.get('oneway') == 'yes' and tags.get('oneway:bus') == 'no' and tags.get('oneway:bicycle') == 'no') # ––––––––––––––––– MORE SPECIALS ––––––––––––––––– cyclestreet = 'highway' in tags and tags.get('cyclestreet') == 'yes' pedestrians_bicycle = tags.get('highway') == 'pedestrian' and tags.get( 'bicycle') == 'yes' pedestrians = tags.get('highway') == 'pedestrian' has_bicycles = tags.get('highway') == 'track' or tags.get( 'highway') == 'path' forbidden = tags.get('bicycle') == 'no' if rl1b: return True, True, 2, 2 elif rm1: return True, True, 2, 2 elif rm2a: return True, False, 2, -1 elif rm2c: return True, False, 2, -1 elif rm2d: return True, True, 2, 2 elif rm2b: return True, False, 2, -1 elif rm3a: return True, True, 1 if (level <= 3 or sidewalk_use) else 0, 2 elif rm3b: return True, True, 1 if (level <= 3 or sidewalk_use) else 0, 2 elif rt2: return True, True, 3, 3 elif rt3: return True, True, 3, 3 elif rt4: return True, True, 3, 1 if (level <= 3 or sidewalk_use) else 0 elif rb6: return True, True, 1 if (level <= 3 or sidewalk_use) else 0, 2 elif rs1: return True, True, 1 if (level <= 3 or sidewalk_use) else 0, 1 elif rs2: return True, True, 2, 3 elif rs3: return True, True, 3, 3 elif rt1: return True, True, 3, 3 elif rs5: return True, True, 3, 3 elif rb1: return True, True, 2, 2 elif rb3: return True, True, 2, 2 elif rb4: return True, False, 2, -1 elif rb5: return True, True, 2, 1 if (level <= 3 or sidewalk_use) else 0 elif rl1a: return True, True, 2, 2 elif rl2: return True, True, 2, 1 if (level <= 3 or sidewalk_use) else 0 elif general_oneway: return True, False, 3, -1 elif general: return True, True, 3, 3 elif cyclestreet: return True, True, 1, 1 elif pedestrians_bicycle: return True, True, 2, 2 elif pedestrians: return True, True, 1, 1 elif has_bicycles: return True, True, 2, 2 elif tags.get('oneway') == 'yes': if get_access(country_iso3, tags.get('highway'), 'bicycle'): return True, False, 1 if (level <= 3 or sidewalk_use) else 0, -1 else: return False, False, -1, -1 else: if get_access(country_iso3, tags.get('highway'), 'bicycle'): return True, True, 1 if (level <= 3 or sidewalk_use) else 0, 1 if ( level <= 3 or sidewalk_use) else 0 else: return False, False, -1, -1
def test_known_country_access(self): self.assertEqual(True, get_access('fra', 'tertiary', 'bicycle')) self.assertEqual(False, get_access('fra', 'motorway', 'bicycle')) self.assertEqual(False, get_access('fra', 'demolished', 'foot')) self.assertEqual(True, get_access('fra', 'stairs', 'foot'))
def way(self, w): osm_id = w.id tags = w.tags attributes = dict() tags = {tag.k: tag.v for tag in w.tags} # 1 GENERAL highway if 'highway' not in tags: if 'foot' not in tags: if 'bicycle' not in tags: if 'pedestrian' not in tags: return else: if tags['pedestrian'] in ['yes', 'true', '1']: attributes['highway'] = 'footway' tags['highway'] = attributes['highway'] else: return else: if tags['bicycle'] in [ 'yes', 'true', '1' ] or tags['bicycle'] == 'designated': attributes['highway'] = 'cycleway' tags['highway'] = attributes['highway'] else: return else: if tags['foot'] in ['yes', 'true', '1']: attributes['highway'] = 'pedestrian' tags['highway'] = attributes['highway'] else: return else: attributes['highway'] = tags['highway'] # 2 GENERAL level according to highway attributes['level'] = get_level(attributes['highway']) if attributes['level'] > self.level_upper_bound or attributes[ 'level'] < self.level_lower_bound: return # 3 GENERAL oneway (oneway, reverse) attributes['oneway'], attributes['reversed'], tags = get_one_way( tags, attributes['highway']) # 4 GENERAL lanes according to level attributes['lanes'] = get_lanes(tags, attributes['level'], attributes['oneway']) # 5 GENERAL width according to lanes attributes['width'] = get_width(tags, attributes['lanes'], attributes['level'], self.country_iso3) # 6 SPECIFIC bicycle with rules attributes['bicycle_forward'], attributes[ 'bicycle_backward'], attributes[ 'bicycle_safety_forward'], attributes[ 'bicycle_safety_backward'] = get_bicycle( tags, attributes['level'], self.country_iso3) # use bicycle lane to create an alternate # 7 SPECIFIC footway with rules attributes['foot'], attributes['foot_safety'] = get_foot( tags, attributes['highway'], attributes['level'], self.country_iso3) # 8 SPECIFIC motorcar with rules maxspeed attributes['maxspeed'] = get_max_speed(tags) attributes['motorcar'] = get_access(self.country_iso3, attributes['highway'], 'motorcar') us = [i.ref for i in w.nodes][:-1] vs = [i.ref for i in w.nodes][1:] for i, (u, v) in enumerate(zip(us, vs)): osm_id_prefix = '{0}-{1}'.format(osm_id, i) if self.directed is False: self.edges_tuples.append( (osm_id_prefix, u, v, attributes['highway'], attributes['oneway'], attributes['level'], attributes['lanes'], attributes['width'], attributes['bicycle_forward'], attributes['bicycle_safety_forward'], attributes['foot'], attributes['foot_safety'], attributes['maxspeed'], attributes['motorcar'])) else: if attributes['oneway'] is False: # add forward edge self.edges_tuples.append( (osm_id_prefix, u, v, attributes['highway'], attributes['oneway'], attributes['level'], attributes['lanes'], attributes['width'], attributes['bicycle_forward'], attributes['bicycle_safety_forward'], attributes['foot'], attributes['foot_safety'], attributes['maxspeed'], attributes['motorcar'])) # add backward edge self.edges_tuples.append( (osm_id_prefix + '-r', v, u, attributes['highway'], attributes['oneway'], attributes['level'], attributes['lanes'], attributes['width'], attributes['bicycle_backward'], attributes['bicycle_safety_backward'], attributes['foot'], attributes['foot_safety'], attributes['maxspeed'], attributes['motorcar'])) else: # if we have to add only one direction BUT bike is authorize in the other way... or Foot... # depending on the country and the access, we add a reverse footway... if attributes['reversed'] is True: self.edges_tuples.append( (osm_id_prefix + '-1', v, u, attributes['highway'], attributes['oneway'], attributes['level'], attributes['lanes'], attributes['width'], attributes['bicycle_backward'], attributes['bicycle_safety_backward'], attributes['foot'], attributes['foot_safety'], attributes['maxspeed'], attributes['motorcar'])) if attributes['bicycle_forward']: self.edges_tuples.append( (osm_id_prefix + '-b', u, v, 'cycleway', attributes['oneway'], get_level('cycleway'), 1, 1.5, attributes['bicycle_forward'], attributes['bicycle_safety_forward'], False, 0, 30, False)) if attributes['foot']: self.edges_tuples.append( (osm_id_prefix + '-f', u, v, 'footway', attributes['oneway'], get_level('footway'), 1, 1.5, False, -1, True, 1, 30, False)) else: self.edges_tuples.append( (osm_id_prefix, u, v, attributes['highway'], attributes['oneway'], attributes['level'], attributes['lanes'], attributes['width'], attributes['bicycle_forward'], attributes['bicycle_safety_forward'], attributes['foot'], attributes['foot_safety'], attributes['maxspeed'], attributes['motorcar'])) if attributes['bicycle_backward']: self.edges_tuples.append( (osm_id_prefix + '-1b', v, u, 'cycleway', attributes['oneway'], get_level('cycleway'), 1, 1.5, attributes['bicycle_backward'], attributes['bicycle_safety_backward'], False, 0, 30, False)) if attributes['foot']: self.edges_tuples.append( (osm_id_prefix + '-1f', v, u, 'footway', attributes['oneway'], get_level('footway'), 1, 1.5, False, -1, True, 1, 30, False))
def test_unknown_country_access(self): self.assertEqual(True, get_access('zzz', 'cycleway', 'bicycle')) self.assertEqual(True, get_access('zzz', 'space_way', 'bicycle'))
def get_foot(tags, highway, level, country_iso3): """ Returns a tuple (foot TRUE|FALSE, safety 0->3) safety -1 - not allowed 0 - no sidewalk and/or level 4-6 1 - sidewalk and/or level 3 2 - designated but shared 3 - designated """ foot = False safety = 0 if tags.get('foot') in [ 'yes', 'true', '1', 'designated' ] or tags.get('footway') in ['yes', 'true', '1', 'designated']: foot = True elif tags.get('pedestrian') in ['yes', 'true', '1']: foot = True elif tags.get('access') in [ 'yes', 'true', '1', 'designated', 'permissive', 'unknown' ]: foot = True elif get_access(country_iso3, highway, 'foot'): foot = True if foot is False: return foot, -1 tags_list = [str(i) for i in tags] if highway in ['pedestrian', 'path']: if tags.get('segregated') == 'yes': safety = 3 elif tags.get('foot') == 'designated': safety = 3 else: safety = 2 elif highway in ['cycleway', 'bicycle']: if tags.get('segregated') == 'yes': safety = 3 elif tags.get('foot') == 'designated': safety = 3 else: safety = 1 elif highway == 'track': safety = 2 elif len(list(filter(sidewalk_pattern.match, tags_list))) > 0: sidewalk = list(filter(sidewalk_pattern.match, tags_list))[0] logging.debug('sidewalk tag is {0}'.format(sidewalk)) if tags.get(sidewalk) not in ['false', 'no', 'none', '0']: safety = 1 elif highway == 'footway': safety = 3 elif level < 2: safety = 2 elif level < 4: safety = 1 return foot, safety