def test_issue_7b(): centroids = np.array([[496712, 232672], [497987, 235942], [496425, 230252], [497482, 234933], [499331, 238351], [496081, 231033], [497090, 233846], [496755, 231645], [498604, 237018]]) n_pts = len(centroids) polygon = Polygon([[495555, 230875], [496938, 235438], [499405, 239403], [499676, 239474], [499733, 237877], [498863, 237792], [499120, 237335], [498321, 235010], [497295, 233185], [497237, 231359], [496696, 229620], [495982, 230047], [496154, 230347], [496154, 230347], [495555, 230875]]) region_polys, region_pts = voronoi_regions_from_coords(centroids, polygon) assert isinstance(region_polys, dict) assert isinstance(region_pts, dict) assert len(region_polys) == len(region_pts) == n_pts assert all([ len(pts_in_region) == 1 for pts_in_region in region_pts.values() ]) # no duplicates fig, ax = subplot_for_map(show_spines=True) plot_voronoi_polys_with_points_in_area(ax, polygon, region_polys, centroids, region_pts) return fig
def createVoronoi(boundary, cities): """process the boundary (polygon border) and points to create the voronoi diagram. Params: boundary (geoDataFrame) : the polygon representing the container of the diagram cities (geoDataFrame) : the points that represent the "seeds" for the diagram Returns: All the datastructures needed to plot the voronoi diagram. Most important for us however, is the "regionPolys" needed for us to determine which ufos are each of the polygons. cityCoords - the seeds converted to proper coordinate system for the diagram boundaryShape - the boundary simplified or converted to a single outer ring polygon regionPolys - a dict of the internal polygons created around each seed regionPoints - a dict of the points used in the creation of the polygon """ # pre-process data so it works with voronoi boundaryProj = boundary.to_crs(epsg=3395) citiesProj = cities.to_crs(boundaryProj.crs) boundaryShape = unary_union(boundaryProj.geometry) cityCoords = points_to_coords(citiesProj.geometry) # create the polygons and such regionPolys, regionPoints = voronoi_regions_from_coords(cityCoords, boundaryShape) # return all the things created so we can use / plot return cityCoords, boundaryShape, regionPolys, regionPoints
def test_voronoi_spain_area_with_plot(): area_shape = _get_country_shape('Spain') coords = _rand_coords_in_shape(area_shape, 20) # generate Voronoi regions region_polys, region_pts = voronoi_regions_from_coords(coords, area_shape) # full checks for voronoi_regions_from_coords() are done in test_voronoi_regions_from_coords_italy() assert isinstance(region_polys, dict) assert isinstance(region_pts, dict) assert len(region_polys) == len(region_pts) assert 0 < len(region_polys) <= 20 # generate covered area region_areas = calculate_polygon_areas( region_polys, m2_to_km2=True) # converts m² to km² assert isinstance(region_areas, dict) assert set(region_areas.keys()) == set(region_polys.keys()) # generate plot fig, ax = subplot_for_map(show_x_axis=True, show_y_axis=True) voronoi_labels = {k: '%d km²' % round(a) for k, a in region_areas.items()} plot_voronoi_polys_with_points_in_area(ax, area_shape, region_polys, coords, region_pts, voronoi_labels=voronoi_labels, voronoi_label_fontsize=7, voronoi_label_color='gray') return fig
def test_voronoi_geopandas_with_plot(): world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres')) cities = gpd.read_file(gpd.datasets.get_path('naturalearth_cities')) # focus on South America, convert to World Mercator (unit: meters) south_am = world[world.continent == 'South America'].to_crs(epsg=3395) cities = cities.to_crs( south_am.crs) # convert city coordinates to same CRS! # create the bounding shape as union of all South American countries' shapes south_am_shape = unary_union(south_am.geometry) south_am_cities = cities[cities.geometry.within( south_am_shape)] # reduce to cities in South America # convert the pandas Series of Point objects to NumPy array of coordinates coords = points_to_coords(south_am_cities.geometry) # calculate the regions region_polys, region_pts = voronoi_regions_from_coords(coords, south_am_shape, per_geom=False) # full checks for voronoi_regions_from_coords() are done in test_voronoi_regions_from_coords_italy() assert isinstance(region_polys, dict) assert isinstance(region_pts, dict) assert len(region_polys) == len(region_pts) == len(coords) # generate plot fig, ax = subplot_for_map(show_spines=True) plot_voronoi_polys_with_points_in_area(ax, south_am_shape, region_polys, coords, region_pts) return fig
def test_voronoi_italy_with_plot(n_pts, per_geom): area_shape = _get_country_shape('Italy') coords = _rand_coords_in_shape(area_shape, n_pts) # generate Voronoi regions region_polys, region_pts = voronoi_regions_from_coords(coords, area_shape, per_geom=per_geom) # full checks for voronoi_regions_from_coords() are done in test_voronoi_regions_from_coords_italy() assert isinstance(region_polys, dict) assert isinstance(region_pts, dict) assert len(region_polys) == len(region_pts) assert 0 < len(region_polys) <= n_pts # generate plot fig, ax = subplot_for_map(show_spines=True) plot_voronoi_polys_with_points_in_area(ax, area_shape, region_polys, coords, region_pts, point_labels=list( map(str, range(len(coords))))) return fig
def split_poly_into_equal_parts(poly, num_parts): ''' ''' points_df = generate_random(2500, poly) km = KMeans(n_clusters=num_parts) points_df.loc[:, 'lat'] = points_df.loc[:, 'geometry'].apply(lambda x: x.y) points_df.loc[:, 'lon'] = points_df.loc[:, 'geometry'].apply(lambda x: x.x) points_for_cluster = points_df.copy() points_for_cluster.drop(labels=['geometry', 'pt_id'], axis=1, inplace=True) kmcls = km.fit(points_for_cluster.values) points_w_cl = points_df.assign(cluster=kmcls.labels_) centers = kmcls.cluster_centers_ centers_gseries = gpd.GeoSeries( map(Point, zip(centers[:, 1], centers[:, 0]))) centroid_coords = np.array( [coords for coords in (zip(centers[:, 1], centers[:, 0]))]) poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords( centroid_coords, poly) poly_shapes_df = gpd.GeoDataFrame(pd.DataFrame(poly_to_pt_assignments, columns=['group']), crs="EPSG:4326", geometry=poly_shapes) return poly_shapes_df
def test_issue_7b(): centroids = np.array([[496712, 232672], [497987, 235942], [496425, 230252], [497482, 234933], [499331, 238351], [496081, 231033], [497090, 233846], [496755, 231645], [498604, 237018]]) polygon = Polygon([[495555, 230875], [496938, 235438], [499405, 239403], [499676, 239474], [499733, 237877], [498863, 237792], [499120, 237335], [498321, 235010], [497295, 233185], [497237, 231359], [496696, 229620], [495982, 230047], [496154, 230347], [496154, 230347], [495555, 230875]]) poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords( centroids, polygon) assert isinstance(poly_shapes, list) assert 0 < len(poly_shapes) <= len(centroids) assert all([isinstance(p, (Polygon, MultiPolygon)) for p in poly_shapes]) assert np.array_equal(points_to_coords(pts), centroids) assert isinstance(poly_to_pt_assignments, list) assert len(poly_to_pt_assignments) == len(poly_shapes) assert all([isinstance(assign, list) for assign in poly_to_pt_assignments]) assert all([len(assign) == 1 for assign in poly_to_pt_assignments ]) # in this case there is a 1:1 correspondance fig, ax = subplot_for_map() plot_voronoi_polys_with_points_in_area(ax, polygon, poly_shapes, centroids, poly_to_pt_assignments) return fig
def create_voronoi(self, towers_for_voronoi, shape): # Create np array of vertices points = towers_for_voronoi.loc[:, ['LNG', 'LAT']].to_numpy() # Create voronoi shapes self.poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords( points, shape) return self.poly_shapes
def test_voronoi_sweden_duplicate_points_with_plot(): area_shape = _get_country_shape('Sweden') coords = _rand_coords_in_shape(area_shape, 20) # duplicate a few points rand_dupl_ind = np.random.randint(len(coords), size=10) coords = np.concatenate((coords, coords[rand_dupl_ind])) poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords( coords, area_shape, accept_n_coord_duplicates=10) assert isinstance(poly_shapes, list) assert 0 < len(poly_shapes) <= 20 assert all([isinstance(p, (Polygon, MultiPolygon)) for p in poly_shapes]) assert np.array_equal(points_to_coords(pts), coords) assert isinstance(poly_to_pt_assignments, list) assert len(poly_to_pt_assignments) == len(poly_shapes) assert all([isinstance(assign, list) for assign in poly_to_pt_assignments]) assert all([0 < len(assign) <= 10 for assign in poly_to_pt_assignments ]) # in this case there is not # everywhere a 1:1 correspondance pts_to_poly_assignments = np.array( get_points_to_poly_assignments(poly_to_pt_assignments)) # make point labels: counts of duplicates per points count_per_pt = [ sum(pts_to_poly_assignments == i_poly) for i_poly in pts_to_poly_assignments ] pt_labels = list(map(str, count_per_pt)) # highlight voronoi regions with point duplicates count_per_poly = np.array(list(map(len, poly_to_pt_assignments))) vor_colors = np.repeat('blue', len(poly_shapes)) # default color vor_colors[count_per_poly > 1] = 'red' # hightlight color fig, ax = subplot_for_map() plot_voronoi_polys_with_points_in_area( ax, area_shape, poly_shapes, coords, plot_voronoi_opts={'alpha': 0.2}, plot_points_opts={'alpha': 0.4}, voronoi_color=list(vor_colors), point_labels=pt_labels, points_markersize=np.array(count_per_pt) * 10) return fig
def test_voronoi_sweden_duplicate_points_with_plot(): area_shape = _get_country_shape('Sweden') coords = _rand_coords_in_shape(area_shape, 20) # duplicate a few points rand_dupl_ind = np.random.randint(len(coords), size=10) coords = np.concatenate((coords, coords[rand_dupl_ind])) n_pts = len(coords) # generate Voronoi regions region_polys, region_pts = voronoi_regions_from_coords(coords, area_shape) # full checks for voronoi_regions_from_coords() are done in test_voronoi_regions_from_coords_italy() assert isinstance(region_polys, dict) assert isinstance(region_pts, dict) assert 0 < len(region_polys) <= n_pts assert 0 < len(region_pts) <= n_pts assert all([ 0 < len(pts_in_region) <= 10 for pts_in_region in region_pts.values() ]) # make point labels: counts of duplicate assignments per points count_per_pt = { pt_indices[0]: len(pt_indices) for pt_indices in region_pts.values() } pt_labels = list(map(str, count_per_pt.values())) distinct_pt_coords = coords[np.asarray(list(count_per_pt.keys()))] # highlight voronoi regions with point duplicates vor_colors = { i_poly: (1, 0, 0) if len(pt_indices) > 1 else (0, 0, 1) for i_poly, pt_indices in region_pts.items() } # generate plot fig, ax = subplot_for_map(show_spines=True) plot_voronoi_polys_with_points_in_area( ax, area_shape, region_polys, distinct_pt_coords, plot_voronoi_opts={'alpha': 0.2}, plot_points_opts={'alpha': 0.4}, voronoi_color=vor_colors, voronoi_edgecolor=(0, 0, 0, 1), point_labels=pt_labels, points_markersize=np.square(np.array(list(count_per_pt.values()))) * 10) return fig
def split_one_poly_into_parts(square_id): ''' ''' logging.info(f"working on shape_id: {square_id}") try: select_square = squares[squares.loc[:, 'SQUARE'] == square_id].copy() if (select_square.geometry.type == 'MultiPolygon').any(): select_square = select_square.explode() address_pts = addresses[addresses.loc[:, 'SQUARE'] == square_id].copy() square_part = 1 for index, one_square in select_square.iterrows(): one_square_shape = one_square['geometry'] address_points_for_cluster = prep_addresses_for_cluster( address_pts, one_square_shape) if len(address_points_for_cluster) < 4: split_type = "equal_area" poly_shapes_df = split_poly_into_equal_parts( one_square_shape, 4) else: split_type = "address_cluster" centroid_coords = find_address_clusters( address_points_for_cluster) poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords( centroid_coords, one_square_shape) poly_shapes_df = gpd.GeoDataFrame(pd.DataFrame( poly_to_pt_assignments, columns=['group']), crs="EPSG:4326", geometry=poly_shapes) poly_shapes_df.loc[:, 'SQUARE'] = square_id poly_shapes_df.loc[:, 'SQUARE_PART'] = square_part if square_part == 1: full_poly_shape_df = poly_shapes_df.copy() else: full_poly_shape_df = full_poly_shape_df.append(poly_shapes_df) square_part += 1 except: bad_shape_df = pd.DataFrame( [[0, Polygon([(0, 0), (1, 1), (0, 1)]), square_id, '', '', 0]], columns=[ 'group', 'geometry', 'SQUARE', 'SSL', 'STNAME', 'SQUARE_PART' ]) full_poly_shape_df = gpd.GeoDataFrame(bad_shape_df, crs="EPSG:4326", geometry='geometry') return full_poly_shape_df
def split_one_poly_into_parts_forplotting(square_id): ''' ''' one_square = squares[squares.loc[:, 'SQUARE'] == square_id].copy() address_pts = addresses[addresses.loc[:, 'SQUARE'] == square_id].copy() address_points_for_cluster = address_pts[['LATITUDE', 'LONGITUDE']].values if len(address_points_for_cluster) < 4: split_type = "equal_area" poly_shapes_df = split_poly_into_equal_parts(one_square.unary_union, 4) else: split_type = "address_cluster" km_silhouette = {} max_cluster = min(10, len(address_points_for_cluster)) # print(f"max_num_clusters = {max_cluster-1}") for i in range(2, max_cluster): km = KMeans(n_clusters=i, random_state=0).fit(address_points_for_cluster) preds = km.predict(address_points_for_cluster) silhouette = silhouette_score(address_points_for_cluster, preds) km_silhouette[silhouette] = i # print("Silhouette score for number of cluster(s) {}: {}".format(i,silhouette)) # print("-"*100) best_num_clusters = max(4, km_silhouette[max(km_silhouette.keys())]) km = KMeans(n_clusters=best_num_clusters, random_state=0).fit(address_points_for_cluster) centers = km.cluster_centers_ centroid_coords = np.array( [coords for coords in (zip(centers[:, 1], centers[:, 0]))]) centers_gseries = gpd.GeoSeries( map(Point, zip(centers[:, 1], centers[:, 0]))) address_pts_w_cluster = address_pts.assign(cluster=km.labels_) centroid_filtered = centers_gseries[centers_gseries.apply( lambda x: one_square.unary_union.contains(x))].copy() centroid_coords_filtered = np.array([ coords for coords in (zip(centroid_filtered.apply(lambda x: x.x), centroid_filtered.apply(lambda x: x.y))) ]) poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords( centroid_coords_filtered, one_square.unary_union) poly_shapes_df = gpd.GeoDataFrame(pd.DataFrame(poly_to_pt_assignments, columns=['group']), crs="EPSG:4326", geometry=poly_shapes) poly_shapes_export = poly_shapes_df.assign(square=square_id) return (poly_shapes_export, address_pts, one_square)
def test_issue_7a(): centroids = np.array([[537300, 213400], [538700, 213700], [536100, 213400]]) n_pts = len(centroids) polygon = Polygon([[540000, 214100], [535500, 213700], [535500, 213000], [539000, 213200]]) region_polys, region_pts = voronoi_regions_from_coords(centroids, polygon) assert isinstance(region_polys, dict) assert isinstance(region_pts, dict) assert len(region_polys) == len(region_pts) == n_pts assert all([ len(pts_in_region) == 1 for pts_in_region in region_pts.values() ]) # no duplicates
def image_gen_main(): coords = hexagonal_lattice(session['ROWS'], session['COLS'], session['NOISE'])[:, :2] x_min, x_max, y_min, y_max = coords[:, 0].min(), coords[:, 0].max( ), coords[:, 1].min(), coords[:, 1].max() bounding_box = Polygon([(x_min, y_min), (x_min, y_max), (x_max, y_max), (x_max, y_min)]) region_polys, _ = voronoi_regions_from_coords(coords, bounding_box) dirname = "/home/suvigya/PycharmProjects/MapGeneratorApp/images/" ocean = 0.07 if int(session['OCEAN']) == 0: ocean = 0 displayMap(list(region_polys.values()), filename=dirname + session['HEXAGON_FILE'], bounds=bounding_box.bounds) multi = [] for poly in region_polys: multi.append(region_polys[poly]) multi = MultiPolygon(multi) cmap = combine_polys(multi, session['DISTRIBUTION']) if ocean != 0: setBoundingOcean(multi, bounding_box.boundary, bounds=(x_max, x_min), cmap=cmap, buffer=ocean, noise=float(session['NOISE'])) else: setBoundingOcean(multi, bounding_box.boundary, bounds=(x_max, x_min), cmap=cmap, buffer=0, noise=0.00) displayMap(multi, fillcolors=cmap, filename=dirname + session['COLORED_W_OCEAN_FILE'], bounds=bounding_box.bounds) with open(dirname + session['WKT_FILE'], "w") as fp: fp.write(multi.wkt) del multi, cmap, region_polys, coords,
def main(): df = pd.read_csv('data.csv', header=None) lon = df[1] lat = df[2] #points = np.delete(df.values, 0, 1) #print(points) box = (0, 0, 15, 15) area = [[0, 0], [15, 0], [15, 13], [13, 13], [13, 15], [0, 15]] ext = [(0, 0), (15, 0), (15, 13), (13, 13), (13, 15), (0, 15)] int = [(11, 12), (12, 12), (12, 11), (11, 11)] grint = [(1, 14), (1, 12), (3, 12), (3, 14)] area_shape = Polygon(ext, [grint, int]) coords = np.random.randint(1, 12, size=(3, 2)) print(coords) points = [] for point in coords: if area_shape.contains(Point(point)) is True: points.append(point) points = coords #points = [point for point in coords if area_shape.contains(Point(point)) is True] print("points:") print(area_shape) vor = spatial.Voronoi(points) #regions, vertices = voronoi_finite_polygons_2d(vor) poly_shapes, pts, poly_to_pt_assignment = voronoi_regions_from_coords( points, area_shape) print(type(poly_shapes)) print(dir(pts)) print(poly_to_pt_assignment) fig, ax = subplot_for_map() plt.figure(dpi=96, figsize=(20 / 96, 20 / 96)) plot_voronoi_polys_with_points_in_area(ax, area_shape, poly_shapes, points, poly_to_pt_assignment) polygons = []
def test_issue_7a(): centroids = np.array([[537300, 213400], [538700, 213700], [536100, 213400]]) polygon = Polygon([[540000, 214100], [535500, 213700], [535500, 213000], [539000, 213200]]) poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords( centroids, polygon) assert isinstance(poly_shapes, list) assert 0 < len(poly_shapes) <= len(centroids) assert all([isinstance(p, (Polygon, MultiPolygon)) for p in poly_shapes]) assert np.array_equal(points_to_coords(pts), centroids) assert isinstance(poly_to_pt_assignments, list) assert len(poly_to_pt_assignments) == len(poly_shapes) assert all([isinstance(assign, list) for assign in poly_to_pt_assignments]) assert all([len(assign) == 1 for assign in poly_to_pt_assignments ]) # in this case there is a 1:1 correspondance
def calculate_apl(self, leaflet="upper"): """ Calculate the area per lipid for the chosen leaflet. :param leaflet: str. The label of the leaflet to calculate APL for. Defaults to "upper". :return: """ # Construct the 2D projection for this leaflet self.get_projection(leaflet=leaflet) # Perform Voronoi tesselation for this projection, bounded by the simulation box. self.voronoi[leaflet] = [voronoi_regions_from_coords(points, bound) for points, bound in zip(self.projection[leaflet], self.data_bounds)] # Calculate the area of each lipid in this leaflet self.apl[leaflet] = [calculate_polygon_areas(i[0]) for i in self.voronoi[leaflet]] # Find the average area per lipid for this leaflet in each frame self.apl_mean[leaflet] = [np.mean(x) for x in self.apl[leaflet]] # Log the result self.add_results(lipid="All", value=self.apl_mean[leaflet], leaflet=leaflet)
def create_voronoi_polygons(self): """ creates Voronoi polygons with `self.antennas_data` as centers, bounded by `self.contour` :return: GeoPandas DF with VCs """ if self.antennas_data.crs == self.contour.crs: coords = points_to_coords(self.antennas_data.geometry) poly_shapes, pts = voronoi_regions_from_coords( coords, self.contour.geometry[0]) voronoi_polygons = gpd.GeoDataFrame({'geometry': poly_shapes}, crs=SWEREF_EPSG) return voronoi_polygons else: logger.error('Objects have different CRSs: %s and %s ' % (self.antennas_data.crs, self.contour.crs))
def test_voronoi_geopandas_with_plot(): world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres')) cities = gpd.read_file(gpd.datasets.get_path('naturalearth_cities')) # focus on South America, convert to World Mercator (unit: meters) south_am = world[world.continent == 'South America'].to_crs(epsg=3395) cities = cities.to_crs( south_am.crs) # convert city coordinates to same CRS! # create the bounding shape as union of all South American countries' shapes south_am_shape = cascaded_union(south_am.geometry) south_am_cities = cities[cities.geometry.within( south_am_shape)] # reduce to cities in South America # convert the pandas Series of Point objects to NumPy array of coordinates coords = points_to_coords(south_am_cities.geometry) # calculate the regions poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords( coords, south_am_shape) assert isinstance(poly_shapes, list) assert 0 < len(poly_shapes) <= len(coords) assert all([isinstance(p, (Polygon, MultiPolygon)) for p in poly_shapes]) assert np.array_equal(points_to_coords(pts), coords) assert isinstance(poly_to_pt_assignments, list) assert len(poly_to_pt_assignments) == len(poly_shapes) assert all([isinstance(assign, list) for assign in poly_to_pt_assignments]) assert all([len(assign) == 1 for assign in poly_to_pt_assignments ]) # in this case there is a 1:1 correspondance fig, ax = subplot_for_map() plot_voronoi_polys_with_points_in_area(ax, south_am_shape, poly_shapes, pts, poly_to_pt_assignments) return fig
def test_voronoi_spain_area_with_plot(): area_shape = _get_country_shape('Spain') coords = _rand_coords_in_shape(area_shape, 20) poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords( coords, area_shape) assert isinstance(poly_shapes, list) assert 0 < len(poly_shapes) <= 20 assert all([isinstance(p, (Polygon, MultiPolygon)) for p in poly_shapes]) assert np.array_equal(points_to_coords(pts), coords) assert isinstance(poly_to_pt_assignments, list) assert len(poly_to_pt_assignments) == len(poly_shapes) assert all([isinstance(assign, list) for assign in poly_to_pt_assignments]) assert all([len(assign) == 1 for assign in poly_to_pt_assignments ]) # in this case there is a 1:1 correspondance poly_areas = calculate_polygon_areas(poly_shapes, m2_to_km2=True) # converts m² to km² assert isinstance(poly_areas, np.ndarray) assert np.issubdtype(poly_areas.dtype, np.float_) assert len(poly_areas) == len(poly_shapes) assert np.all(poly_areas > 0) fig, ax = subplot_for_map(show_x_axis=True, show_y_axis=True) voronoi_labels = ['%d km²' % round(a) for a in poly_areas] plot_voronoi_polys_with_points_in_area(ax, area_shape, poly_shapes, coords, poly_to_pt_assignments, voronoi_labels=voronoi_labels, voronoi_label_fontsize=7, voronoi_label_color='gray') return fig
def test_voronoi_italy_with_plot(): area_shape = _get_country_shape('Italy') coords = _rand_coords_in_shape(area_shape, 100) poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords( coords, area_shape) assert isinstance(poly_shapes, list) assert 0 < len(poly_shapes) <= 100 assert all([isinstance(p, (Polygon, MultiPolygon)) for p in poly_shapes]) assert np.array_equal(points_to_coords(pts), coords) assert isinstance(poly_to_pt_assignments, list) assert len(poly_to_pt_assignments) == len(poly_shapes) assert all([isinstance(assign, list) for assign in poly_to_pt_assignments]) assert all([len(assign) == 1 for assign in poly_to_pt_assignments ]) # in this case there is a 1:1 correspondance fig, ax = subplot_for_map() plot_voronoi_polys_with_points_in_area(ax, area_shape, poly_shapes, coords, poly_to_pt_assignments) return fig
# Display map display_map(gdf, chicago, proj) # TO DO: maps well, but how to grab features of voronois? ############################################################################### # FIND VORONOIS (plots a map and gets bounds?) ############################################################################### # from: https://github.com/WZBSocialScienceCenter/geovoronoi from geovoronoi import voronoi_regions_from_coords points = np.array(list(cps_df.coordinates)) chicago_bounds = chicago.iloc[0].geometry # TO DO: gets error abour hull distance or something poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords( points, chicago_bounds) ############################################################################### vor = Voronoi(points) voronoi_plot_2d(vor) new_point = [50, 50] plt.plot(new_point[0], new_point[1], 'ro') point_index = np.argmin(np.sum((points - new_point)**2, axis=1)) ridges = np.where(vor.ridge_points == point_index)[0] vertex_set = set(np.array(vor.ridge_vertices)[ridges, :].ravel()) region = [x for x in vor.regions if set(x) == vertex_set][0] polygon = vor.vertices[region] plt.fill(*zip(*polygon), color='yellow')
schools = [] schoolx = [] schooly = [] for i in range(50): x = random.randint(0, 99) y = random.randint(0, 99) if [x, y] not in streetsarr and [x, y] not in schools: schools.append([x, y]) schoolx.append(x) schooly.append(y) plt.plot(schoolx, schooly, 'bs') # разбивам плоскость на диаграму вороного coords = schools boundary_shape = shapely.geometry.box(0, 0, 100, 100, ccw=True) poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords( coords, boundary_shape) #xt=int(input("Введите координату xlearn: ")) #yt=int(input("Введите координату ylearn: ")) xt = yt = 50 for i in range(len(poly_shapes)): if shapely.geometry.Point(xt, yt).within(poly_shapes[i]): x, y = poly_shapes[i].exterior.xy plt.plot(x, y, color="pink") plt.plot(xt, yt, "go") plt.plot(schools[poly_to_pt_assignments[i][0]][0], schools[poly_to_pt_assignments[i][0]][1], "ro") plt.show()
n_pts = len(pts) print( 'will use %d of %d randomly generated points that are inside geographic area' % (n_pts, N_POINTS)) coords = points_to_coords(pts) # convert back to simple NumPy coordinate array del pts #%% # # calculate the Voronoi regions, cut them with the geographic area shape and assign the points to them # region_polys, region_pts = voronoi_regions_from_coords(coords, area_shape) # calculate area in km², too poly_areas = calculate_polygon_areas(region_polys, m2_to_km2=True) # converts m² to km² print('areas in km²:') pprint(poly_areas) print('sum:') print(sum(poly_areas.values())) #%% plotting fig, ax = subplot_for_map(show_x_axis=True, show_y_axis=True)
def main(fn: str = "large_metro_voronoi.geojson", extra_metro_cbsa_ids: List[str] = []): logger.info("Loading files") us_outline = load_us_outline() ipm_gdf = load_ipm_shapefile() ipm_gdf["convex_hull"] = ipm_gdf.convex_hull # site_locations = load_site_locations() metro_gdf = load_metro_areas_shapefile() logger.info("Finding largest metros") if extra_metro_cbsa_ids: logger.info( f"The extra metros {extra_metro_cbsa_ids} will be included") largest_metros = find_largest_cities( metro_areas_gdf=metro_gdf, ipm_gdf=ipm_gdf, min_population=750000, extra_metro_cbsa_ids=extra_metro_cbsa_ids, ) logger.info("Making voronoi polygons") poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords( largest_metros[["longitude", "latitude"]].values, us_outline) metro_voronoi = largest_metros.iloc[[x[0] for x in poly_to_pt_assignments], :] metro_voronoi["metro_id"] = metro_voronoi["cbsa_id"] metro_voronoi.geometry = poly_shapes logger.info("Fixing NYC/Long Island") ny_z_j_poly = ipm_gdf.loc[ipm_gdf["IPM_Region"] == "NY_Z_J", "convex_hull"].values[0] ny_z_k_poly = ipm_gdf.loc[ipm_gdf["IPM_Region"] == "NY_Z_K", "convex_hull"].values[0] ny_z_j_k_poly = cascaded_union([ny_z_j_poly, ny_z_k_poly]) for cbsa_id in metro_voronoi.query( "IPM_Region.isin(['NENG_CT', 'PJM_EMAC']).values" )["cbsa_id"].to_list(): # print(cbsa_id) metro_voronoi.loc[metro_voronoi["cbsa_id"] == cbsa_id, "geometry"] = metro_voronoi.loc[ metro_voronoi["cbsa_id"] == cbsa_id, "geometry"].difference(ny_z_j_k_poly) # Need the unary_union to make geometries valid ny_z_j_ipm = shapely.ops.unary_union( ipm_gdf.loc[ipm_gdf["IPM_Region"] == "NY_Z_J", "geometry"].values[0]) ny_z_k_ipm = shapely.ops.unary_union( ipm_gdf.loc[ipm_gdf["IPM_Region"] == "NY_Z_K", "geometry"].values[0]) # Get a simplified outline of Long Island # Start with the zone K convex hull, remove the overlap with zone J IPM region, # then take the intersection with the US outline. ny_z_k_ipm = ny_z_k_poly.difference(ny_z_j_ipm).intersection(us_outline) # Same with NYC, zone J. Remove the bordering regions (zone K, other IPM regions) # from the convex hull, then take intersection with US outline. ny_z_j_ipm = (ny_z_j_poly.difference(ny_z_k_ipm).difference( shapely.ops.unary_union( ipm_gdf.query("IPM_Region=='PJM_EMAC'") ["geometry"].values[0])).difference( shapely.ops.unary_union( ipm_gdf.query("IPM_Region=='NY_Z_G-I'") ["geometry"].values[0])).intersection(us_outline)) data_dict = { "IPM_Region": ["NY_Z_J", "NY_Z_K"], "state": ["NY", "NY"], "metro_id": ["NY_Z_J", "NY_Z_K"], "latitude": [ny_z_j_ipm.centroid.y, ny_z_k_ipm.centroid.y], "longitude": [ny_z_j_ipm.centroid.x, ny_z_k_ipm.centroid.x], } ny_z_j_k_df = gpd.GeoDataFrame(data=data_dict, geometry=[ny_z_j_ipm, ny_z_k_ipm], crs=metro_voronoi.crs) final_metro_voronoi = pd.concat([metro_voronoi, ny_z_j_k_df], ignore_index=True, sort=False) logger.info("Writing polygons to file") cols = ["IPM_Region", "geometry", "latitude", "longitude", "metro_id"] final_metro_voronoi[cols].to_file(fn, driver="GeoJSON")
def computeCrossProduct(self, reference_old_entries, second_old_entries): # 1. Reference distribution is regions, second dist is regions # - uniform distribute overlap of regions # 2. Reference distribution is regions, second dist is points # - map points to regions and perform as usual # 3. Reference distribution is points, second dist is regions # - create regions from reference dist. points with Voronoi diagram # 4. Reference distribution is points, second dist is points # - " " if 'POLYGON' in reference_old_entries[0]: if 'POLYGON' in second_old_entries[0]: # For 1. compute cross product for new regions new_entries = SpatialHelper.computeNewRegions( reference_old_entries, second_old_entries) #print('inside spatial handler') #print(len(reference_old_entries)) #print(len(second_old_entries)) #print(len(new_entries)) #print('leaving spatial handler') elif 'POINT' in second_old_entries[0] or \ type(second_old_entries[0]) is tuple: # For 2., don't need to compute cross product # Just use Regions of reference distribution new_entries = reference_old_entries elif 'POINT' in reference_old_entries[0] or \ type(reference_old_entries[0]) is tuple: # For 3. compute Voronoi ref_points_obj = SpatialHelper.getGeoObjectsFromString( list(set(reference_old_entries))) sec_regions_obj = SpatialHelper.getGeoObjectsFromString( second_old_entries) sec_regions_obj_union = unary_union(sec_regions_obj) for point in ref_points_obj: #Remove points from reference that are outside sec_region_union if not point.within(sec_regions_obj_union): raise ValueError( "Points from reference distribution lie outside union of regions from secondary distribution." ) #ref_points_obj.remove(point) #train_df = train_df[train_df.Region != (point.x,point.y)] coords = points_to_coords(ref_points_obj) ref_vor_regions_obj, pts, poly_to_pt_assignments = voronoi_regions_from_coords( coords, sec_regions_obj_union) #Convert back to string ref_vor_regions = SpatialHelper.convertGeoObjectsToString( ref_vor_regions_obj) #print(ref_vor_regions[0]) new_entries = SpatialHelper.computeNewRegions( ref_vor_regions, second_old_entries) # For 3. and 4., return error for now #raise ValueError("Invalid input for the {} variable. Spatial\ # mismatch variables of the reference distribution\ # must be 'Multipolygon' or 'Polygon.'" # .format(str(self.node))) #print('inside spatial handler') #print(len(reference_old_entries)) #print(len(second_old_entries)) #print(len(new_entries)) #print('leaving spatial handler') else: raise ValueError("Invalid input for {} variable. Spatial mismatch\ variables must be a 'Multipolygon', 'Polygon'\ or 'Point', or be a tuple of (X,Y) coordinates.". format(str(self.node))) return reference_old_entries, second_old_entries, new_entries
print('duplicated %d random points -> we have %d coordinates now' % (N_DUPL, len(coords))) # if we didn't know in advance how many duplicates we have (and which points they are), we could find out like this: # unique_coords, unique_ind, dupl_counts = np.unique(coords, axis=0, return_index=True, return_counts=True) # n_dupl = len(coords) - len(unique_ind) # n_dupl # >>> 10 # # calculate the Voronoi regions, cut them with the geographic area shape and assign the points to them # # the duplicate coordinates will belong to the same voronoi region # poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords( coords, area_shape, accept_n_coord_duplicates=N_DUPL) # poly_to_pt_assignments is a nested list because a voronoi region might contain several (duplicate) points print('\n\nvoronoi region to points assignments:') for i_poly, pt_indices in enumerate(poly_to_pt_assignments): print('> voronoi region', i_poly, '-> points', str(pt_indices)) print('\n\npoints to voronoi region assignments:') pts_to_poly_assignments = np.array( get_points_to_poly_assignments(poly_to_pt_assignments)) for i_pt, i_poly in enumerate(pts_to_poly_assignments): print('> point ', i_pt, '-> voronoi region', i_poly) # # plotting
def update(self, outer_pos, inner_pos, UPDATE, EPS=0.1): global t t = time.time() - start outputs = [] global FLAG if FLAG: fig, ax = subplot_for_map() global ax, fig FLAG = False def reshape_coords(coords): new_coords = [] for p in poly_shapes: for n in coords: m = Point(n) if m.within(p): new_coords.append(n) return new_coords def reshape_centroids(centroids): new_centroids = [] for p in poly_shapes: for n in centroids: m = Point(n) if m.within(p): new_cent roids.append(n) return new_centroids def match_pair(poly_shapes, coords, new_centroids): sorted_coords = [] points = coords_to_points(coords) for i, p in enumerate(points): c = coords[i] #print("c: ", c[0],c[1]) for j, poly in enumerate(poly_shapes): if p.within(poly): pair = new_centroids[j] sorted_coords.append(pair) return sorted_coords N = 4 #len(inner_pos) area_shape = Polygon(outer_pos) #update_outer(outer_pos) # generate some random points within the bounds minx, miny, maxx, maxy = area_shape.bounds pts = [p for p in coords_to_points(inner_pos) if p.within(area_shape)] # converts to shapely Point while len(pts) < N: #isinstance(compensated, int): inner_pos = points_to_coords(pts) print('%d of %d drone"s pos is available' % (len(pts), N)) #print("compensated!!", compensated, type(compensated)) randx = np.random.uniform(minx, maxx, N - len(pts)) randy = np.random.uniform(miny, maxy, N - len(pts)) compensated = np.vstack((randx, randy)).T inner_pos = np.append(inner_pos, compensated, axis=0) #print(inner_pos) #inner_pos = inner_pos[sorted(np.random.choice(inner_pos.shape[0], N, replace=False)), :] pts = [ p for p in coords_to_points(inner_pos) if p.within(area_shape) ] # converts to shapely Point ax.clear() # comment out if you want to plot trajectory coords = points_to_coords( pts) # convert back to simple NumPy coordinate array poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords( coords, area_shape, accept_n_coord_duplicates=0) poly_centroids = np.array([p.centroid.coords[0] for p in poly_shapes]) #new_centroids = reshape_centroids(poly_centroids) # plotting EPS = EPS err = 99999 #old_coords = coords new_centroids = match_pair(poly_shapes, coords, poly_centroids) for i in range(len(coords)): xo = coords[i][0] yo = coords[i][1] #old_coords[i][0] = xo #old_coords[i][1] = yo xc = new_centroids[i][0] yc = new_centroids[i][1] #err = np.sqrt((xo-xc)**2 + (yo-yc)**2) data = [xc, yc] outputs.append(data) #(np.array((xc, yc)).astype(np.float64)) #if err > EPS: # # print("UPDARED!!") # coords[i][0] = xc#xo + 0.2*(xc-xo) # coords[i][1] = yc#yo + 0.2*(yc-yo) # draw centroid that each drone follow for i, centroid in enumerate(new_centroids): c1 = centroid ax.plot(c1[0], c1[1], '*', label=str(i)) for coord in coords: c = coord ax.plot(c[0], c[1], 'o', alpha=0.5) fig = plot_voronoi_polys_with_points_in_area(ax, area_shape, poly_shapes, coords, poly_to_pt_assignments) plt.title(str(t) + "[s]") plt.pause(0.00001) return outputs
def build_voronoi(us_outline, ipm_gdf, largest_metros, extra_metro_cbsa_ids: List[str] = []): logger.info("Making voronoi polygons") poly_shapes, pts, poly_to_pt_assignments = voronoi_regions_from_coords( largest_metros[["longitude", "latitude"]].values, us_outline) metro_voronoi = largest_metros.iloc[[x[0] for x in poly_to_pt_assignments], :] metro_voronoi["metro_id"] = metro_voronoi["cbsa_id"] metro_voronoi.geometry = poly_shapes logger.info("Fixing NYC/Long Island") ny_z_j_poly = ipm_gdf.loc[ipm_gdf["IPM_Region"] == "NY_Z_J", "convex_hull"].values[0] ny_z_k_poly = ipm_gdf.loc[ipm_gdf["IPM_Region"] == "NY_Z_K", "convex_hull"].values[0] ny_z_j_k_poly = cascaded_union([ny_z_j_poly, ny_z_k_poly]) for cbsa_id in metro_voronoi.query( "IPM_Region.isin(['NENG_CT', 'PJM_EMAC']).values" )["cbsa_id"].to_list(): # print(cbsa_id) metro_voronoi.loc[metro_voronoi["cbsa_id"] == cbsa_id, "geometry"] = metro_voronoi.loc[ metro_voronoi["cbsa_id"] == cbsa_id, "geometry"].difference(ny_z_j_k_poly) # Need the unary_union to make geometries valid ny_z_j_ipm = shapely.ops.unary_union( ipm_gdf.loc[ipm_gdf["IPM_Region"] == "NY_Z_J", "geometry"].values[0]) ny_z_k_ipm = shapely.ops.unary_union( ipm_gdf.loc[ipm_gdf["IPM_Region"] == "NY_Z_K", "geometry"].values[0]) # Get a simplified outline of Long Island # Start with the zone K convex hull, remove the overlap with zone J IPM region, # then take the intersection with the US outline. ny_z_k_ipm = ny_z_k_poly.difference(ny_z_j_ipm).intersection(us_outline) # Same with NYC, zone J. Remove the bordering regions (zone K, other IPM regions) # from the convex hull, then take intersection with US outline. ny_z_j_ipm = (ny_z_j_poly.difference(ny_z_k_ipm).difference( shapely.ops.unary_union( ipm_gdf.query("IPM_Region=='PJM_EMAC'") ["geometry"].values[0])).difference( shapely.ops.unary_union( ipm_gdf.query("IPM_Region=='NY_Z_G-I'") ["geometry"].values[0])).intersection(us_outline)) data_dict = { "IPM_Region": ["NY_Z_J", "NY_Z_K"], "state": ["NY", "NY"], "metro_id": ["NY_Z_J", "NY_Z_K"], "latitude": [ny_z_j_ipm.centroid.y, ny_z_k_ipm.centroid.y], "longitude": [ny_z_j_ipm.centroid.x, ny_z_k_ipm.centroid.x], } ny_z_j_k_df = gpd.GeoDataFrame(data=data_dict, geometry=[ny_z_j_ipm, ny_z_k_ipm], crs=metro_voronoi.crs) final_metro_voronoi = pd.concat([metro_voronoi, ny_z_j_k_df], ignore_index=True, sort=False) # Assign the Sacramento metro to WEC_BANC rather than WEC_CALN final_metro_voronoi.loc[final_metro_voronoi["metro_id"] == "40900", "IPM_Region"] = "WEC_BANC" return final_metro_voronoi
buffer = valleypoly.buffer(BUFFER_DISTANCE) features = [0] geometry = [valleypoly] df = {'features': features, 'geometry': geometry} gdf = gpd.GeoDataFrame(df) gdf.to_file('C:/Users/pmitc/Documents/QGIS/Zumbro/Zumbro_SamplePoints/TestGround/ValleyPoly.shp') features = [0] geometry = [buffer] df = {'features': features, 'geometry': geometry} gdf = gpd.GeoDataFrame(df) gdf.to_file('C:/Users/pmitc/Documents/QGIS/Zumbro/Zumbro_SamplePoints/TestGround/ValleyBuffer.shp') # Create Voronoi Polygons region_polys, region_pts = voronoi_regions_from_coords(points, buffer) #Export the voronoi polygons features = [i for i in range(len(region_polys))] geometry = [geom for geom in region_polys.values()] df = {'features': features, 'geometry': geometry} gdf = gpd.GeoDataFrame(df) gdf.to_file('C:/Users/pmitc/Documents/QGIS/Zumbro/Zumbro_SamplePoints/TestGround/Voronoi_Demo.shp') print("Voronoi Polygons created.") voronoi_edges = [] for poly in region_polys.values(): if poly.geom_type == 'MultiPolygon': # If the buffer distance is too small (<0.0006 in this case), some of the voronoi outputs are MultiPolygons.