def get_shortest_route(self, start, end):
        """
        Gets the shortest route by given start and end node.
        For departure, end node must be a runway node.
        For arrival, end node must be a gate node.
        Assume the arrival start point is outside of Spot.
        """
        # GEO_MIDDLE_NORTH = {"lat": 37.122000, "lng": -122.079057}
        # SP1 = Spot("SP1", GEO_MIDDLE_NORTH)
        if end in self.runway_nodes:
            if start not in self.depart_routing_table[end]:
                return None
            return self.depart_routing_table[end][start]

        if type(end) == Gate:
            spot = end.get_spots()
            # spot = SP1
            gate_to_spot = self.arrival_routing_table[spot][end]
            gate_to_spot_links = gate_to_spot.get_links()
            spot_to_gate = Route(spot, end, [])
            for i in range(len(gate_to_spot_links) - 1, -1, -1):
                spot_to_gate.add_link(gate_to_spot_links[i].reverse)

            if type(start) == Spot:
                return spot_to_gate
            node_to_spot = self.arrival_routing_table[spot][start]
            result = Route(start, end, [])
            result.add_links(node_to_spot.get_links())
            result.add_links(spot_to_gate.get_links())
            return result

        raise Exception("End node is not a runway node nor a gate node.")