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]])
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)