예제 #1
0
    def generate_voronoi_nodes(self):
        # TODO: If this is not the first construction of the voronoi cells, can any existing node info be kept?
        # Structures must be emptied if this is not the first time constructing the voronoi cells
        self.all_boundary_nodes = list()
        self.all_cells = list()
        self.all_centre_nodes = dict()
        self.all_edges = list()
        # SphericalVoronoi object can be queried for various point and edge information
        self.spherical_voronoi = jellymatter_voronoi.SphericalVoronoi(self.voronoi_sites)

        # Create node objects used for holding world information
        # Adjacent cells share boundary nodes, so dictionary is used to look up if SpatialNode has already been
        #  created for given location
        self.boundary_nodes_by_location = dict()
        self.edges_by_location = dict()
        for cell_index, cell_boundary_points in enumerate(self.spherical_voronoi.faces):
            cell_boundary_nodes = list()
            locations = cartesian_utils.cartesian_to_geographic(cell_boundary_points)
            # Every intersection point is represented by a SpatialNode
            for i in range(len(locations)):
                longitude, latitude = locations[i]
                x, y, z = cell_boundary_points[i]
                key = (longitude, latitude)
                # Use dict to re-use SpatialNode if it has already been created for this location
                node = None
                if key in self.boundary_nodes_by_location:
                    # Node already exists, so re-use
                    node = self.boundary_nodes_by_location[key]
                else:
                    # Node does not already exist, so create
                    node = nodetools.SpatialNode(longitude, latitude, x, y, z)
                    self.boundary_nodes_by_location[key] = node
                    self.all_boundary_nodes.append(node)
                cell_boundary_nodes.append(node)
            # Cell boundary nodes form a ring of neighbour relations
            for i in range(len(cell_boundary_nodes)):
                cell_boundary_nodes[i].add_neighbour(cell_boundary_nodes[i-1])
                node_relationship_key = frozenset([(cell_boundary_nodes[i].longitude, cell_boundary_nodes[i].latitude), (cell_boundary_nodes[i-1].longitude, cell_boundary_nodes[i-1].latitude)])
                if node_relationship_key not in self.edges_by_location:
                    node_relationship = [cell_boundary_nodes[i], cell_boundary_nodes[i-1]]
                    self.edges_by_location[node_relationship_key] = node_relationship
                    self.all_edges.append(node_relationship)

            # Create non-neighbour node for voronoi site at centre of cell
            location = tuple(cartesian_utils.cartesian_to_geographic([self.voronoi_sites[cell_index]])[0])
            centre_node = nodetools.SpatialNode(location[0], location[1], self.voronoi_sites[cell_index][0], self.voronoi_sites[cell_index][1], self.voronoi_sites[cell_index][2])
            self.all_centre_nodes[location] = centre_node

            # Store Cell object keyed on (lon, lat) tuple
            self.all_cells.append(nodetools.Cell(centre_node, cell_boundary_nodes))

        # Use delaunay connections to determine which Cell objects are adjacent to each other
        # across a voronoi boundary so they can be given a neighbour relationship
        for cell_indices in self.spherical_voronoi.hull.simplices:
            cells_in_tri = list()
            for i, cell_index in enumerate(cell_indices):
                # Enforce neighbour relationship between adjacent cells
                self.all_cells[cell_indices[i]].add_neighbour(self.all_cells[cell_indices[i-1]])
예제 #2
0
    def test_cartesian_to_geographic(self):
        north_pole = [0, 0, 1]
        south_pole = [0, 0, -1]
        equatorial_point_a = [1, 0, 0] # Near Sao Tome and Principe
        equatorial_point_b = [-1, 0, 0] # Near Phoenix Islands, Pacific Ocean
        equatorial_point_c = [0, 1, 0] # Near Malaysia
        equatorial_point_d = [0, -1, 0] # Near Galapagos Islands

        cart_points = [north_pole, south_pole, equatorial_point_a, equatorial_point_b, equatorial_point_c, equatorial_point_d]
        geog_points = cartesian_utils.cartesian_to_geographic(cart_points)

        self.assertEqual(geog_points[0][1], 90)
        self.assertEqual(geog_points[1][1], -90)
        self.assertEqual(geog_points[2][0], 0)
        self.assertEqual(abs(geog_points[3][0]), 180)
        self.assertEqual(geog_points[4][0], 90)
        self.assertEqual(geog_points[5][0], -90)

        print(geog_points)