Example #1
0
    def test_the_simplest_merging_of_ways(self):
        # road between two junctions may be in OSM represented by any number of ways
        # typical case for split is that one of road attributes changes - for example
        # surface, lane count, part of bridge is tunnel or any other change
        # road may be also split without any reason whatsoever, and it is a
        # valid tagging

        # TODO - how tags should be merged? Throw them away?
        # Just use tags from random way? How tags are used by converter?

        result = Result(elements=[], api=None)
        start = Node(node_id=1, lat=1, lon=-10, attributes={}, result=result)
        middle = Node(node_id=2, lat=2, lon=-50, attributes={}, result=result)
        end = Node(node_id=3, lat=3, lon=-50, attributes={}, result=result)

        way_a = Way(way_id=1,
                    center_lat=1.5,
                    center_lon=-30,
                    node_ids=[start.id, middle.id],
                    attributes={},
                    result=result)
        way_b = Way(way_id=2,
                    center_lat=2.5,
                    center_lon=-50,
                    node_ids=[middle.id, end.id],
                    attributes={},
                    result=result)

        result.append(start)
        result.append(middle)
        result.append(end)
        result.append(way_a)
        result.append(way_b)

        self.assertEqual(len(result.ways), 2)
        self.assertEqual(len(result.nodes), 3)

        result = ConverterNormalizer.simplify_loaded_data(result)
        ConverterNormalizer.validate_returned_data(result)

        self.assertEqual(len(result.ways), 1)
        nodes = {}
        for node in result.nodes:
            nodes[node.id] = node
        self.assertTrue(1 in nodes)
        self.assertTrue(3 in nodes)
        node_a = nodes[1]
        node_b = nodes[3]
        self.assertEqual(node_a.id, 1)
        self.assertEqual(node_a.lat, 1)
        self.assertEqual(node_a.lon, -10)
        self.assertEqual(node_b.id, 3)
        self.assertEqual(node_b.lat, 3)
        self.assertEqual(node_b.lon, -50)
Example #2
0
    def test_p_shaped_topology(self):
        # this test possible case that caused an unexpected bug
        # due to splitting and deduplication P shape should be reduced to single way (| shape)

        result = Result(elements=[], api=None)
        start_of_long_way = Node(node_id=1,
                                 lat=1,
                                 lon=-10,
                                 attributes={},
                                 result=result)
        end_of_long_way = Node(node_id=2,
                               lat=5,
                               lon=-90,
                               attributes={},
                               result=result)
        junction = Node(node_id=4,
                        lat=3,
                        lon=-50,
                        attributes={},
                        result=result)

        long_way = Way(
            way_id=1,
            center_lat=3,
            center_lon=-50,
            node_ids=[start_of_long_way.id, junction.id, end_of_long_way.id],
            attributes={},
            result=result)
        short_way = Way(way_id=2,
                        center_lat=3,
                        center_lon=-75,
                        node_ids=[junction.id, start_of_long_way.id],
                        attributes={},
                        result=result)

        result.append(start_of_long_way)
        result.append(end_of_long_way)
        result.append(junction)
        result.append(long_way)
        result.append(short_way)

        self.assertEqual(len(result.ways), 2)
        self.assertEqual(len(result.nodes), 3)

        result = ConverterNormalizer.simplify_loaded_data(result)
        ConverterNormalizer.validate_returned_data(result)

        expected_way_count = 1
        self.assertEqual(len(result.ways), expected_way_count)
        self.assertEqual(len(result.nodes), 2)
        for i in range(expected_way_count):
            self.assertEqual(len(result.ways[i].get_nodes()), 2)
Example #3
0
    def test_from_overpass_api(self):
      result = Result()
      nodes = [Node("5902860", 49.2759, -123.1242, result=result), Node("5899705", 49.2766, -123.1231, result=result), Node("5902472", 49.2748, -123.1258, result=result), Node("553185065", 49.2775075, -123.1267388, result=result)]
      ways = [Way("201058", ["5902860", "5899705", "5902472"], result=result), Way("301878980", ["5899705","553185065"], result=result)]
      for element in nodes + ways:
        result.append(element)
      graph = OSMGraph.from_overpy_result(result)

      expected_ways = [OSMWay("201058-0", ["5902860", "5899705"]), OSMWay("201058-1", ["5899705", "5902472"]), OSMWay("301878980-0", ["5899705", "553185065"])]
      expected_nodes = [OSMNode("5902860", 49.2759, -123.1242), OSMNode("5899705", 49.2766, -123.1231), OSMNode("5902472", 49.2748, -123.1258), OSMNode("553185065", 49.2775075, -123.1267388)]

      self.assertEqual(sorted(list(graph.ways.values())), sorted(expected_ways))
      self.assertEqual(sorted(list(graph.nodes.values())), sorted(expected_nodes))
Example #4
0
    def test_selfvalidator_only_one_way_between_nodes(self):
        result = Result(elements=[], api=None)
        start = Node(node_id=1, lat=1, lon=-10, attributes={}, result=result)
        end = Node(node_id=3, lat=3, lon=-50, attributes={}, result=result)

        way_a = Way(way_id=1,
                    center_lat=1.5,
                    center_lon=-30,
                    node_ids=[start.id, end.id],
                    attributes={},
                    result=result)
        way_b = Way(way_id=2,
                    center_lat=1.5,
                    center_lon=-30,
                    node_ids=[start.id, end.id],
                    attributes={},
                    result=result)
        result.append(start)
        result.append(end)
        result.append(way_a)
        result.append(way_b)
        #ConverterNormalizer.only_one_way_between_nodes(result)
        self.assertRaises(ConverterNormalizer.ConversionFailed,
                          ConverterNormalizer.only_one_way_between_nodes,
                          result)
        ConverterNormalizer.validate_returned_data(
            ConverterNormalizer.simplify_loaded_data(result))
    def generate_new_result_from_ways_structure(result, ways,
                                                lowest_available_way_id):
        remade_result = Result(elements=[], api=None)
        nodes_left = set()
        for way_id, nodes_list in ways.items():
            for node in nodes_list:
                nodes_left.add(node)

        for id in nodes_left:
            remade_result.append(result.get_node(id))

        removed_ways_count = 0

        unique_ids = set()
        for way_id, nodes_list in ways.items():
            # node_a to node_b, node_b to node_a are considered the same by Kraksim
            if nodes_list[0] < nodes_list[1]:
                nodes_list = nodes_list[::-1]
            kraksim_id = str(nodes_list[0]) + str(nodes_list[1])
            if kraksim_id in unique_ids:
                removed_ways_count += 1
            else:
                unique_ids.add(kraksim_id)
                base_way = result.get_way(way_id)
                remade_way = ConverterNormalizer.remade_way(
                    base_way, remade_result, nodes_list)
                remade_result.append(remade_way)

        return remade_result, removed_ways_count
Example #6
0
 def test_roundabout_crash_regression(self):
     result = Result(elements=[], api=None)
     node = Node(node_id=1, lat=1, lon=1, attributes={}, result=result)
     result.append(node)
     node = Node(node_id=2, lat=1, lon=1, attributes={}, result=result)
     result.append(node)
     way = Way(way_id=88655958,
               center_lat=1,
               center_lon=1,
               node_ids=[
                   1,
                   2,
                   1,
               ],
               attributes={},
               result=result)
     result.append(way)
     ConverterNormalizer.validate_returned_data(
         ConverterNormalizer.simplify_loaded_data(result))
Example #7
0
    def test_remove_duplicated_ways(self):
        result = Result(elements=[], api=None)
        start = Node(node_id=1, lat=1, lon=-10, attributes={}, result=result)
        end = Node(node_id=3, lat=3, lon=-50, attributes={}, result=result)

        way_a = Way(way_id=1,
                    center_lat=1.5,
                    center_lon=-30,
                    node_ids=[start.id, end.id],
                    attributes={},
                    result=result)
        way_b = Way(way_id=2,
                    center_lat=1.5,
                    center_lon=-30,
                    node_ids=[start.id, end.id],
                    attributes={},
                    result=result)
        result.append(start)
        result.append(end)
        result.append(way_a)
        result.append(way_b)
        self.assertEqual(len(result.ways), 2)
        self.assertEqual(len(result.nodes), 2)
        result = ConverterNormalizer.simplify_loaded_data(result)
        ConverterNormalizer.validate_returned_data(result)
        self.assertEqual(len(result.ways), 1)
        self.assertEqual(len(result.nodes), 2)
        node_a = result.nodes[0]
        node_b = result.nodes[1]
        if node_a.id != 1:
            node_a, node_b = node_b, node_a
        self.assertEqual(node_a.id, 1)
        self.assertEqual(node_a.lat, 1)
        self.assertEqual(node_a.lon, -10)
        self.assertEqual(node_b.id, 3)
        self.assertEqual(node_b.lat, 3)
        self.assertEqual(node_b.lon, -50)
Example #8
0
    def test_removal_of_nodes_not_changing_topology_of_road_graph(self):
        # for us geometry of ways is not relevant, only topology is important
        # so nodes that are on exactly one way and
        # are not its start/end (forming dead end) should be discarded

        result = Result(elements=[], api=None)
        start = Node(node_id=1, lat=1, lon=10, attributes={}, result=result)
        discarding_1 = Node(node_id=2,
                            lat=2,
                            lon=20,
                            attributes={},
                            result=result)
        discarding_2 = Node(node_id=3,
                            lat=3,
                            lon=30,
                            attributes={},
                            result=result)
        discarding_3 = Node(node_id=4,
                            lat=4,
                            lon=40,
                            attributes={},
                            result=result)
        end = Node(node_id=5, lat=5, lon=50, attributes={}, result=result)

        result.append(start)
        result.append(discarding_1)
        result.append(discarding_2)
        result.append(discarding_3)
        result.append(end)

        node_list_for_way = [
            start.id, discarding_1.id, discarding_2.id, discarding_3.id, end.id
        ]
        way = Way(way_id=1,
                  center_lat=3,
                  center_lon=30,
                  node_ids=node_list_for_way,
                  attributes={},
                  result=result)
        result.append(way)

        self.assertEqual(len(result.ways), 1)
        self.assertEqual(len(result.nodes), 5)

        self.assertEqual(start.id, 1)
        self.assertEqual(start.lat, 1)
        self.assertEqual(start.lon, 10)
        self.assertEqual(end.id, 5)
        self.assertEqual(end.lat, 5)
        self.assertEqual(end.lon, 50)

        result = ConverterNormalizer.simplify_loaded_data(result)
        ConverterNormalizer.validate_returned_data(result)

        self.assertEqual(len(result.ways), 1)
        self.assertEqual(len(result.nodes), 2)
        node_a = result.nodes[0]
        node_b = result.nodes[1]
        if node_a.id != 1:
            node_a, node_b = node_b, node_a
        self.assertEqual(node_a.id, 1)
        self.assertEqual(node_a.lat, 1)
        self.assertEqual(node_a.lon, 10)
        self.assertEqual(node_b.id, 5)
        self.assertEqual(node_b.lat, 5)
        self.assertEqual(node_b.lon, 50)
Example #9
0
 def test_missing_attached_ways_recalculation_regression(self):
     result = Result(elements=[], api=None)
     node = Node(node_id=1, lat=1, lon=1, attributes={}, result=result)
     result.append(node)
     node = Node(node_id=2, lat=1, lon=1, attributes={}, result=result)
     result.append(node)
     node = Node(node_id=3, lat=1, lon=1, attributes={}, result=result)
     result.append(node)
     node = Node(node_id=4, lat=1, lon=1, attributes={}, result=result)
     result.append(node)
     way = Way(way_id=10,
               center_lat=1,
               center_lon=1,
               node_ids=[
                   1,
                   2,
               ],
               attributes={},
               result=result)
     result.append(way)
     way = Way(way_id=11,
               center_lat=1,
               center_lon=1,
               node_ids=[
                   3,
                   4,
               ],
               attributes={},
               result=result)
     result.append(way)
     way = Way(way_id=12,
               center_lat=1,
               center_lon=1,
               node_ids=[
                   4,
                   1,
               ],
               attributes={},
               result=result)
     result.append(way)
     ConverterNormalizer.validate_returned_data(
         ConverterNormalizer.simplify_loaded_data(result))
Example #10
0
 def test_crash_on_isolated_node(self):
     result = Result(elements=[], api=None)
     node = Node(node_id=251680825,
                 lat=1,
                 lon=1,
                 attributes={},
                 result=result)
     result.append(node)
     node = Node(node_id=30372051,
                 lat=1,
                 lon=1,
                 attributes={},
                 result=result)
     result.append(node)
     node = Node(node_id=1924449568,
                 lat=1,
                 lon=1,
                 attributes={},
                 result=result)
     result.append(node)
     node = Node(node_id=1325756454,
                 lat=1,
                 lon=1,
                 attributes={},
                 result=result)
     result.append(node)
     way = Way(way_id=216999581,
               center_lat=1,
               center_lon=1,
               node_ids=[30372051, 1325756454, 251680825],
               attributes={},
               result=result)
     result.append(way)
     ConverterNormalizer.validate_returned_data(
         ConverterNormalizer.simplify_loaded_data(result))
Example #11
0
    def test_selfvalidator_no_nodes_on_exactly_two_ways(self):
        result = Result(elements=[], api=None)
        start = Node(node_id=1, lat=1, lon=10, attributes={}, result=result)
        discarding_1 = Node(node_id=2,
                            lat=2,
                            lon=20,
                            attributes={},
                            result=result)
        middle = Node(node_id=4, lat=4, lon=40, attributes={}, result=result)
        end = Node(node_id=5, lat=5, lon=50, attributes={}, result=result)

        result.append(start)
        result.append(middle)
        result.append(end)

        way_a = Way(way_id=1,
                    center_lat=3,
                    center_lon=30,
                    node_ids=[start.id, middle.id],
                    attributes={},
                    result=result)
        result.append(way_a)
        way_b = Way(way_id=2,
                    center_lat=3,
                    center_lon=30,
                    node_ids=[middle.id, end.id],
                    attributes={},
                    result=result)
        result.append(way_b)
        self.failUnlessRaises(ConverterNormalizer.ConversionFailed,
                              ConverterNormalizer.no_nodes_on_exactly_two_ways,
                              result)
        ConverterNormalizer.validate_returned_data(
            ConverterNormalizer.simplify_loaded_data(result))
Example #12
0
    def test_selfvalidator_each_way_connects_two_nodes(self):
        result = Result(elements=[], api=None)
        start_of_long_way = Node(node_id=1,
                                 lat=1,
                                 lon=-10,
                                 attributes={},
                                 result=result)
        end_of_long_way = Node(node_id=2,
                               lat=5,
                               lon=-90,
                               attributes={},
                               result=result)
        junction = Node(node_id=4,
                        lat=3,
                        lon=-50,
                        attributes={},
                        result=result)
        node_for_short_way = Node(node_id=5,
                                  lat=3,
                                  lon=-100,
                                  attributes={},
                                  result=result)

        long_way = Way(
            way_id=1,
            center_lat=3,
            center_lon=-50,
            node_ids=[start_of_long_way.id, junction.id, end_of_long_way.id],
            attributes={},
            result=result)
        short_way = Way(way_id=2,
                        center_lat=3,
                        center_lon=-75,
                        node_ids=[junction.id, node_for_short_way.id],
                        attributes={},
                        result=result)

        result.append(start_of_long_way)
        result.append(end_of_long_way)
        result.append(junction)
        result.append(node_for_short_way)
        result.append(long_way)
        result.append(short_way)
        self.failUnlessRaises(ConverterNormalizer.ConversionFailed,
                              ConverterNormalizer.each_way_connects_two_nodes,
                              result)
        ConverterNormalizer.validate_returned_data(
            ConverterNormalizer.simplify_loaded_data(result))
Example #13
0
    def test_the_simplest_splitting_of_ways(self):
        # in OSM way may end at any place - juction is just node connected to multiple ways
        # it is possible to have a real junction formed by two ways joining, it is also
        # possible to have nodes that belong to two ways, without a real junction
        # (both ways end at that node and are representing a single road)

        result = Result(elements=[], api=None)
        start_of_long_way = Node(node_id=1,
                                 lat=1,
                                 lon=-10,
                                 attributes={},
                                 result=result)
        end_of_long_way = Node(node_id=2,
                               lat=5,
                               lon=-90,
                               attributes={},
                               result=result)
        junction = Node(node_id=4,
                        lat=3,
                        lon=-50,
                        attributes={},
                        result=result)
        node_for_short_way = Node(node_id=5,
                                  lat=3,
                                  lon=-100,
                                  attributes={},
                                  result=result)

        long_way = Way(
            way_id=1,
            center_lat=3,
            center_lon=-50,
            node_ids=[start_of_long_way.id, junction.id, end_of_long_way.id],
            attributes={},
            result=result)
        short_way = Way(way_id=2,
                        center_lat=3,
                        center_lon=-75,
                        node_ids=[junction.id, node_for_short_way.id],
                        attributes={},
                        result=result)

        result.append(start_of_long_way)
        result.append(end_of_long_way)
        result.append(junction)
        result.append(node_for_short_way)
        result.append(long_way)
        result.append(short_way)

        self.assertEqual(len(result.ways), 2)
        self.assertEqual(len(result.nodes), 4)

        result = ConverterNormalizer.simplify_loaded_data(result)
        ConverterNormalizer.validate_returned_data(result)

        expected_way_count = 3
        self.assertEqual(len(result.ways), expected_way_count)
        self.assertEqual(len(result.nodes), 4)
        for i in range(expected_way_count):
            self.assertEqual(len(result.ways[i].get_nodes()), 2)