def hex_bins(osm_buffer_gpkg_path, study_area, gdf_osm_destinations_clipped): boundary = gpd.read_file(osm_buffer_gpkg_path, layer="urban_study_region") gdf_boundary = boundary["geometry"] xmin, ymin, xmax, ymax = gdf_boundary.total_bounds # lat-long of 2 corners xmin -= 500 xmax += 500 ymin -= 500 ymax += 500 # East-West extent of urban_study_region EW = xmax - xmin # North-South extent of urban_study_region NS = ymax - ymin # Hexagon bins diameter should equal 500 meters d = 500 # horizontal width of hexagon = w = d* sin(60) w = d * np.sin(np.pi / 3) # Approximate number of hexagons per row = EW/w n_cols = int(EW / d) + 1 # Approximate number of hexagons per column = NS/d n_rows = int(NS / w) + 1 w = (xmax - xmin) / n_cols # width of hexagon d = w / np.sin(np.pi / 3) # diameter of hexagon 500 meters array_of_hexes = [] # +1 added to n_rows since the range function runs from 0 through (n-1), and the number of rows of hexgons plotted # was one less than the expcted number of rows. for rows in range(0, n_rows + 1): hcoord = np.arange(xmin, xmax, w) + (rows % 2) * w / 2 vcoord = [ymax - rows * d * 0.75] * n_cols for x, y in zip(hcoord, vcoord): hexes = RegularPolygon((x, y), numVertices=6, radius=d / 2, alpha=0.2, edgecolor="k") verts = hexes.get_path().vertices trans = hexes.get_patch_transform() points = trans.transform(verts) array_of_hexes.append(Polygon(points)) # turn study_area polygon into gdf with correct CRS gdf_boundary = gpd.GeoDataFrame(geometry=[study_area], crs=gdf_osm_destinations_clipped.crs) gdf_boundary = gpd.GeoDataFrame(gdf_boundary) hex_grid = gpd.GeoDataFrame({"geometry": array_of_hexes}) hex_grid_clipped = gpd.overlay(hex_grid, gdf_boundary) hex_grid_clipped = gpd.GeoDataFrame(hex_grid_clipped, geometry="geometry") return gdf_boundary, hex_grid_clipped
def make_hexmap(MAREA=None, d=300): '''Takes a shapefile and fills it with hexagons of diameter d. Args: MAREA (GeoDataFrame) : Polygon of boundaries of a given city. d : desired hexagon diameter Returns: gdf (GeoDataFrame) : Hexagon grid GeoDataFrame ''' xmin, ymin, xmax, ymax = MAREA.total_bounds # lat-long of 2 corners #East-West extent of Toronto = 42193 metres EW = haversine((xmin, ymin), (xmax, ymin)) # North-South extent of Toronto = 30519 metres NS = haversine((xmin, ymin), (xmin, ymax)) # diameter of each hexagon in the grid = 900 metres d = 300 # horizontal width of hexagon = w = d* sin(60) w = d * np.sin(np.pi / 3) # Approximate number of hexagons per row = EW/w n_cols = int(EW / w) + 1 # Approximate number of hexagons per column = NS/d n_rows = int(NS / d) + 1 # Make hexagons w = (xmax - xmin) / n_cols # width of hexagon d = w / np.sin(np.pi / 3) #diameter of hexagon array_of_hexes = [] for rows in range(0, n_rows): hcoord = np.arange(xmin, xmax, w) + (rows % 2) * w / 2 vcoord = [ymax - rows * d * 0.75] * n_cols for x, y in zip(hcoord, vcoord): #, colors): hexes = RegularPolygon((x, y), numVertices=6, radius=d / 2, alpha=0.2, edgecolor='k') verts = hexes.get_path().vertices trans = hexes.get_patch_transform() points = trans.transform(verts) array_of_hexes.append(Polygon(points)) #ax.add_patch(hexes) # make final geodataframe hex_grid = gpd.GeoDataFrame({'geometry': array_of_hexes}, crs={'init': 'epsg:4326'}) MAREA_hex = gpd.overlay(hex_grid, MAREA) #MAREA_hex = hex_grid MAREA_hex = gpd.GeoDataFrame(MAREA_hex, geometry='geometry') MAREA_hex = MAREA_hex.reset_index() return MAREA_hex
class ClipWindow: def __init__(self, ax, line): self.ax = ax ax.set_title('drag polygon around to test clipping') self.canvas = ax.figure.canvas self.line = line self.poly = RegularPolygon((200, 200), numVertices=10, radius=100, facecolor='yellow', alpha=0.25, transform=transforms.IdentityTransform()) ax.add_patch(self.poly) self.canvas.mpl_connect('button_press_event', self.onpress) self.canvas.mpl_connect('button_release_event', self.onrelease) self.canvas.mpl_connect('motion_notify_event', self.onmove) self.x, self.y = None, None def onpress(self, event): self.x, self.y = event.x, event.y def onrelease(self, event): self.x, self.y = None, None def onmove(self, event): if self.x is None: return dx = event.x - self.x dy = event.y - self.y self.x, self.y = event.x, event.y x, y = self.poly.xy x += dx y += dy #print self.y, event.y, dy, y self.poly.xy = x, y self._clip() def _clip(self): self.line.set_clip_path(self.poly.get_path(), self.poly.get_transform()) self.canvas.draw_idle()
class ClipWindow: def __init__(self, ax, line): self.ax = ax ax.set_title('drag polygon around to test clipping') self.canvas = ax.figure.canvas self.line = line self.poly = RegularPolygon( (200, 200), numVertices=10, radius=100, facecolor='yellow', alpha=0.25, transform=transforms.IdentityTransform()) ax.add_patch(self.poly) self.canvas.mpl_connect('button_press_event', self.onpress) self.canvas.mpl_connect('button_release_event', self.onrelease) self.canvas.mpl_connect('motion_notify_event', self.onmove) self.x, self.y = None, None def onpress(self, event): self.x, self.y = event.x, event.y def onrelease(self, event): self.x, self.y = None, None def onmove(self, event): if self.x is None: return dx = event.x - self.x dy = event.y - self.y self.x, self.y = event.x, event.y x, y = self.poly.xy x += dx y += dy #print self.y, event.y, dy, y self.poly.xy = x,y self._clip() def _clip(self): self.line.set_clip_path(self.poly.get_path(), self.poly.get_transform()) self.canvas.draw_idle()
def get_nodes_within_hexagon(self, center, radius, stream_id): """ Get nodes inside a hexagon :param center: x+yj :param radius: float :param stream_id: str :return: array of ints (neuron indices) """ output_grid = self.corem_positions[stream_id] hexagon = RegularPolygon((center.real, center.imag), 6, radius=radius) hexagon_path = hexagon.get_path( ) # matplotlib returns the unit hexagon hexagon_tf = hexagon.get_transform( ) # which can then be transformed to give the real path real_hexagon_path = hexagon_tf.transform_path(hexagon_path) output_grid_tuples = [(z.real, z.imag) for z in output_grid] wanted_indices = np.where( real_hexagon_path.contains_points(output_grid_tuples)) return wanted_indices[0]
# Approximate number of hexagons per column = NS/d n_rows = int(NS / d) + 10 # Make a hexagonal grid to cover the entire area from matplotlib.patches import RegularPolygon ax = TIME_EDGES.boundary.plot(edgecolor='black', figsize=(20, 60)) w = (xmax - xmin) / n_cols # width of hexagon d = w / np.sin(np.pi / 3) # diameter of hexagon array_of_hexes = [] for rows in range(0, n_rows): hcoord = np.arange(xmin, xmax, w) + (rows % 2) * w / 2 vcoord = [ymax - rows * d * 0.75] * n_cols for x, y in zip(hcoord, vcoord): # , colors): hexes = RegularPolygon((x, y), numVertices=6, radius=d / 2, alpha=0.2, edgecolor='k') verts = hexes.get_path().vertices trans = hexes.get_patch_transform() points = trans.transform(verts) array_of_hexes.append(Polygon(points)) ax.add_patch(hexes) ax.set_xlim([xmin, xmax]) ax.set_ylim([ymin, ymax]) hex_grid = gpd.GeoDataFrame({'geometry': array_of_hexes}, crs={'init': 'epsg:4326'}) # hex_grid = gpd.GeoDataFrame({'geometry':array_of_hexes},crs={'init':'epsg:3035'}) # hex_grid.plot() ############################################################################################# # create basemap ave_LAT = 37.53988692816245