def __filter_way(self, way, mask_edges): oneway = "oneway" in way.tags and way.tags["oneway"] not in [ "no", "0", "false" ] if oneway: reverse = way.tags["oneway"] in ["-1", "reverse"] way_nodes = way.nodes if not reverse else reversed(way.nodes) nodes = self.__edges_to_set(pairwise(way_nodes), mask_edges) way.nodes = nodes.items if reverse: way.tags["oneway"] = "yes" else: edges = OrderedSet( [edge for edge in pairwise(way.nodes) if edge in mask_edges]) reversed_edges = OrderedSet([ edge for edge in pairwise(list(reversed(way.nodes))) if edge in mask_edges ]) reversed_reversed_edges = OrderedSet( [edge[::-1] for edge in reversed(reversed_edges)]) if edges == reversed_reversed_edges: way.nodes = self.__edges_to_set(edges, mask_edges).items else: return self.__handle_non_matching_directions( edges, reversed_edges, reversed_reversed_edges, way, mask_edges) return [way]
def way(self, w): node_ids = [node.ref for node in w.nodes] if "highway" in w.tags and ( any(pair in self.mask.edges for pair in pairwise(node_ids)) or any(pair in self.mask.edges for pair in pairwise(list(reversed(node_ids))))): tags = dict(version=w.version, **{tag.k: tag.v for tag in w.tags}) self.ways[w.id] = Way(w.id, node_ids, tags=tags)
def __is_relation_valid(self, via_node_id, way_id, node_id): way = self.ways.get(way_id, None) if way is None: return False way_nodes = way.nodes edges = pairwise(way_nodes) edges.extend(pairwise(list(reversed(way_nodes)))) if any(relation_edge in edges for relation_edge in [(via_node_id, node_id), (node_id, via_node_id)]): return True return False
def _find_restriction(self, nodes, from_way): for i, node in enumerate(nodes): # If it's starting point, only coming from opposite direction it could have a restriction if i == 0: continue neighbours = { edge[1] for edge in self.mask.edges if edge[0] == node } for neighbour in neighbours: if neighbour not in nodes: from_node = nodes[i - 1] to_node = neighbour seq = (from_node, node, to_node) if (seq in self.mask.relations or any(node_id not in self.mask.nodes for node_id in seq) or any(edge not in self.mask.edges for edge in pairwise(seq))): continue to_way = None for possible_way in self.nodes[neighbour].ways: if all(n in self.ways[possible_way].nodes for n in [node, neighbour]): to_way = possible_way if to_way: if self.relations.get(seq): self.relations[seq].from_node = from_node self.relations[seq].to_node = to_node else: relation_ids = { relation.id for key, relation in self.relations.items() if relation.id } tags = { "type": "restriction", "restriction": self.__add_relation_metadata(seq), "version": 1, } self.relations[seq] = Relation( id=max(relation_ids) + 1 if relation_ids else 0, from_way=from_way, from_node=from_node, to_way=to_way, to_node=to_node, via=ViaNode(node), tags=tags, )
def test_pairwise(): iterable_1 = [1, 2, 3, 4] iterable_2 = (1, 2, 3, 4) iterable_3 = (1, ) expected_pairs_1 = [(1, 2), (2, 3), (3, 4)] expected_pairs_2 = [(1, 2), (2, 3), (3, 4)] expected_pairs_3 = [] pairs_1 = pairwise(iterable_1) pairs_2 = pairwise(iterable_2) pairs_3 = pairwise(iterable_3) assert pairs_1 == expected_pairs_1 assert pairs_2 == expected_pairs_2 assert pairs_3 == expected_pairs_3
def _decompose_match(self, match): nodes, edges, relations = set(), set(), set() for matching in match.metadata["raw"]["matchings"]: for leg in matching["legs"]: leg_nodes = leg["nodes"] nodes.update(leg_nodes) edges.update(pairwise(leg_nodes)) relations.update(tripletwise(leg_nodes)) return nodes, edges, relations
def __add_relation_metadata(self, seq): edge_1, edge_2 = pairwise(seq) nodes_edge_1 = [self.nodes[node] for node in edge_1] nodes_edge_2 = [self.nodes[node] for node in edge_2] vector_1 = create_vector(nodes_edge_1) vector_2 = create_vector(nodes_edge_2) # TODO: Handle u-turns and straight_on return calculate_direction(vector_1, vector_2)