def test_get_network_methods(): import geopandas as gpd north, south, east, west = 37.79, 37.78, -122.41, -122.43 with httmock.HTTMock(get_mock_response_content('overpass-response-6.json.gz')): G1 = ox.graph_from_bbox(north, south, east, west, network_type='drive_service') with httmock.HTTMock(get_mock_response_content()): G1 = ox.graph_from_bbox(north, south, east, west, network_type='drive_service', truncate_by_edge=True) location_point = (37.791427, -122.410018) bbox = ox.bbox_from_point(location_point, project_utm=True) with httmock.HTTMock(get_mock_response_content('overpass-response-8.json.gz')): G2 = ox.graph_from_point(location_point, distance=750, distance_type='bbox', network_type='drive') with httmock.HTTMock(get_mock_response_content('overpass-response-9.json.gz')): G3 = ox.graph_from_point(location_point, distance=500, distance_type='network') with httmock.HTTMock(get_mock_response_content('overpass-response-10.json.gz')): G4 = ox.graph_from_address(address='350 5th Ave, New York, NY', distance=1000, distance_type='network', network_type='bike') places = ['Los Altos, California, USA', {'city':'Los Altos Hills', 'state':'California'}, 'Loyola, California'] with httmock.HTTMock(get_mock_response_content('overpass-response-11.json.gz')): G5 = ox.graph_from_place(places, network_type='all', clean_periphery=False) calif = gpd.read_file('tests/input_data/ZillowNeighborhoods-CA') mission_district = calif[(calif['CITY']=='San Francisco') & (calif['NAME']=='Mission')] polygon = mission_district['geometry'].iloc[0] with httmock.HTTMock(get_mock_response_content('overpass-response-12.json.gz')): G6 = ox.graph_from_polygon(polygon, network_type='walk')
def get_data_from_user(self): #Taking input self.origin_lat = input("Please enter the Latitude of the Origin \n") self.origin_long = input("Please enter the Longitude of the Origin \n") print("Latitude of origin : ", float(self.origin_lat), " and Longitude of origin", float(self.origin_long)) self.dest_lat = input( "Please enter the Latitude of the Destination \n") self.dest_long = input( "Please enter the Longitude of the Destination \n") print("Latitude of destination : ", float(self.dest_lat), " and Longitude of destination", float(self.dest_long)) self.extra_travel = float( input( "Please enter the percentage of shortest path between above points that you are willing to travel extra \n" )) print("x% : ", self.extra_travel) self.mode = input( "To minimize elevation, please type 'minimize' \n To maximize elevation, please type 'maximize'" ) if self.mode not in self.VALID_MODES: print("Mode invalid") sys.exit() self.G_proj, self.G = self.get_map() self.origin = ox.get_nearest_node(self.G, (float( self.origin_lat), float(self.origin_long))) #(37.77, -122.426)) self.destination = ox.get_nearest_node(self.G, (float( self.dest_lat), float(self.dest_long))) #(37.773, -122.441)) self.bbox = ox.bbox_from_point( (float(self.origin_lat), float(self.origin_long)), distance=1500, project_utm=True)
def test_get_network_methods(): from shapely import wkt # graph from bounding box north, south, east, west = 37.79, 37.78, -122.41, -122.43 G1 = ox.graph_from_bbox(north, south, east, west, network_type='drive_service') G1 = ox.graph_from_bbox(north, south, east, west, network_type='drive_service', truncate_by_edge=True) # graph from point location_point = (37.791427, -122.410018) bbox = ox.bbox_from_point(location_point, project_utm=True) G2 = ox.graph_from_point(location_point, distance=750, distance_type='bbox', network_type='drive') G3 = ox.graph_from_point(location_point, distance=500, distance_type='network') # graph from address G4 = ox.graph_from_address(address='350 5th Ave, New York, NY', distance=1000, distance_type='network', network_type='bike') # graph from list of places places = ['Los Altos, California, USA', {'city':'Los Altos Hills', 'state':'California'}, 'Loyola, California'] G5 = ox.graph_from_place(places, network_type='all', clean_periphery=False) # graph from polygon polygon = wkt.loads('POLYGON ((-122.418083 37.754154, -122.418082 37.766028, -122.410909 37.766028, -122.410908 37.754154, -122.418083 37.754154))') G6 = ox.graph_from_polygon(polygon, network_type='walk') # test custom query filter filtr = ('["area"!~"yes"]' '["highway"!~"motor|proposed|construction|abandoned|platform|raceway"]' '["foot"!~"no"]' '["service"!~"private"]' '["access"!~"private"]') G = ox.graph_from_point(location_point, network_type='walk', custom_filter=filtr)
def study_area_from_point(point, distance): """ Define a study area from a center point and distance to edge of bounding box. Returns a GeoDataFrame for plotting and for summary data. Parameters ---------- point : tuple the (lat, lon) point to create the bounding box around distance : int how many meters the north, south, east, and west sides of the box should each be from the point Returns ------- GeoDataFrame """ # use osmnx to define the bounding box bbox = ox.bbox_from_point(point, distance) # split the tuple n, s, e, w = bbox # Create GeoDataFrame study_area = gpd.GeoDataFrame() # create geometry column with bounding box polygon study_area.loc[0, 'geometry'] = Polygon([(w, s), (w, n), (e, n), (e, s)]) # set the name of the gdf study_area.gdf_name = 'study_area' study_area.crs = {'init': 'epsg:4326'} return study_area
def get_bounding_box(self, start_location, end_location, distance=2000): """ Returns the bounding box (N,S,E,W) given the start and end coordinates. Params: start_location: tuple (lat,long) end_location: tuple (lat,long) distance: Additional width given to the bbox at the corners(in metres) Returns: bbox: tuple (n,s,e,w) """ bbox1 = ox.bbox_from_point(start_location, distance) bbox2 = ox.bbox_from_point(end_location, distance) bbox = (max(bbox1[0], bbox2[0]), min(bbox1[1], bbox2[1]), max(bbox1[2], bbox2[2]), min(bbox1[3], bbox2[3])) return bbox
def random_points_in_bbox(latitude, longitude, distance, num_points): bbox = ox.bbox_from_point((latitude, longitude), distance=distance) min_latitude = min(bbox[0], bbox[1]) diff_latitude = abs(bbox[0] - bbox[1]) min_longitude = min(bbox[2], bbox[3]) diff_longitude = abs(bbox[2] - bbox[3]) lat_long_pair = [] for i in range(num_points): u_lat = np.random.uniform(0.0001, diff_latitude) lat = min_latitude + u_lat u_long = np.random.uniform(0.0001, diff_longitude) lgtd = min_longitude + u_long lat_long_pair.append([lat, lgtd]) return lat_long_pair
def test_bbox_from_points_with_margins(): bbox = get_bbox(size = "medium") nw = core.Point(bbox.north, bbox.west) sw = core.Point(bbox.south, bbox.west) ne = core.Point(bbox.north, bbox.east) se = core.Point(bbox.south, bbox.east) points = [nw, sw, ne, se] bbox = core.bbox_from_points(points) expected_bbox = core.BBox(*ox.bbox_from_point( point= (54.97351405, -1.62545930208892), distance = 500)) assert_bbox_almost_equal(bbox, expected_bbox, decimal = 3)
def get_bbox(size): if size == "small": return core.BBox(54.97092396, 54.97080711, -1.622966153, -1.622935367) elif size == "medium": return core.BBox(*ox.bbox_from_point( point= (54.97351405, -1.62545930208892), distance = 500)) elif size == "uk": return core.BBox(59.478568831926395, 49.82380908513249, -10.8544921875, 2.021484375) else: raise ValueError("No such bbox size")
def draw_bounding_box(origin_x, origin_y, destination_x, destination_y, graph): origin = ox.get_nearest_node(G, (origin_x, origin_y)) destination = ox.get_nearest_node(G, (destination_x, destination_y)) lat3, lon3 = calculate_midpoint(origin_x, origin_y, destination_x, destination_y) #Calculate distance between origin and destination #determine distance from midpoint to edge of bounding box distance = calculate_distance_between_two_nodes(origin_x, origin_y, destination_x, destination_y) bbox = ox.bbox_from_point((lat3, lon3), distance=distance, project_utm=True) return origin, destination, bbox
def test_small_bbox_from_points(): point1, point2 = get_points() bbox = get_bbox(size = "small") nw = core.Point(bbox.north, bbox.west) sw = core.Point(bbox.south, bbox.west) ne = core.Point(bbox.north, bbox.east) se = core.Point(bbox.south, bbox.east) points = [nw, sw, ne, se] bbox = core.bbox_from_points(points) expected_bbox = core.BBox(*ox.bbox_from_point( point= core.get_meanpoint([point1, point2]), distance = 100)) assert_bbox_almost_equal(bbox, expected_bbox)
def get_input(self): #origin_lat, origin_long, dest_lat, dest_long, overhead, mode = self.view.get_data() # testing without input origin_lat, origin_long, dest_lat, dest_long, overhead, mode = 42.3524, -71.06643, 42.358226, -71.061260, 10, "minimize" #getting graph + graph with projections graph_projection, graph_orig = self.get_map() origin = ox.get_nearest_node( graph_orig, (float(origin_lat), float(origin_long))) # (37.77, -122.426)) destination = ox.get_nearest_node( graph_orig, (float(dest_lat), float(dest_long))) # (37.773, -122.441)) bbox = ox.bbox_from_point((float(origin_lat), float(origin_long)), distance=1500, project_utm=True) #setting model's attributes self.model.set_origin(origin) self.model.set_dest(destination) self.model.set_overhead(overhead) self.model.set_mode(mode) self.model.set_bbox(bbox) self.model.set_graph_projection(graph_projection)
def projected_study_area_from_point(point, distance): """ Define study area from center point and distance to edge of bounding box. Return this as a projected GeoDataFrame for plotting and for summary data. Parameters ---------- point : tuple the (lat, lon) point to create the bounding box around distance : int how many meters the north, south, east, and west sides of the box should each be from the point Returns ------- GeoDataFrame """ # use osmnx to define the bounding box, always return the crs bbox = ox.bbox_from_point(point, distance, project_utm=True, return_crs=True) # split the tuple n, s, e, w, crs_code = bbox # Create GeoDataFrame study_area = gpd.GeoDataFrame() # create geometry column with bounding box polygon study_area.loc[0, 'geometry'] = Polygon([(w, s), (w, n), (e, n), (e, s)]) # create column with area in hectares study_area['area_m2'] = study_area.area # set the crs of the gdf study_area.crs = crs_code # set the name of the gdf study_area.gdf_name = 'study_area' return study_area
# NYC # centre = (40.750638, -73.993899) # fnameIN = 'nyc-data.csv' # fnameQueries = 'nyc-queries.csv' # fnameShape = 'nyc' # fnamePickle = 'nyc-pickle.txt' # Load data path = '/Collective Shortest Paths/' os.chdir(path) queries = pd.read_csv(fnameIN, header=0) nRecords = queries.shape[0] # Get bounding box station_box = ox.bbox_from_point(centre, distance=1500, project_utm=False, return_crs=False) south = station_box[1] north = station_box[0] east = station_box[2] west = station_box[3] # Get graph G = ox.graph_from_bbox(north, south, east, west, network_type='drive', retain_all=True) G = nx.convert_node_labels_to_integers(G) nodes, edges = ox.graph_to_gdfs(G)
Created on Thu Jul 27 15:32:11 2017 @author: yangjinyue """ import osmnx as ox from IPython.display import Image ox.config(log_file=True, log_console=True, use_cache=True) img_folder = 'images' extension = 'png' size = 600 point = (35.691502, 139.703481) dist = 2000 gdf = ox.buildings_from_point(point=point, distance=dist, retain_invalid=True) gdf_proj = ox.project_gdf(gdf) bbox = ox.bbox_from_point(point=point, distance=dist, project_utm=True) fig, ax = ox.plot_buildings(gdf_proj, bgcolor='#333333', color='w', figsize=(8, 8), bbox=bbox, save=True, show=False, close=True, filename='paris_bldgs', dpi=150) Image('{}/{}.{}'.format(img_folder, 'paris_bldgs', extension), height=size, width=size)
G_proj = ox.project_graph(G) # In[25]: nc = ox.get_node_colors_by_attr(G_proj, 'elevation', cmap='plasma', num_bins=20) fig, ax = ox.plot_graph(G_proj, fig_height=6, node_color=nc, node_size=12, node_zorder=2, edge_color='#dddddd') # In[46]: origin = ox.get_nearest_node(G, (42.3778, -72.5198)) destination = ox.get_nearest_node(G, (42.3898, -72.5283)) bbox = ox.bbox_from_point((42.384, -72.524), distance=1500, project_utm=True) # In[47]: def impedance(length, grade): penalty = grade ** 2 return length * penalty # add impedance and elevation rise values to each edge in the projected graph # use absolute value of grade in impedance function if you want to avoid uphill and downhill for u, v, k, data in G_proj.edges(keys=True, data=True): data['impedance'] = impedance(data['length'], data['grade_abs']) data['rise'] = data['length'] * data['grade']
def draw_local_map(self, curr_gps): """ generates subgrah by recieving vehicle GPS points. First the Nan GPS points are excluded. Then these GPS points are converted to UTM co-ordinates and the distance between Current point and starting point is calculated and the flag=1 at beginning so the current GPS point is considered as old point and the bounding box is generated from this point to be passed as arguement for downloading the local_map.The local_map is then downloaded from OSM API, and the flag is set to 0. This to generate a local_map as soon as the first gps Reading is recieved. The next local_maps are generated every time the vehicle moves a certain distance by measuring distance between the old GPS and current GPS points. If this distance is exceed, the current GPS is set to be old Point, and the a local_map is downloaded and stored as .xml file in the same way. Parameters: curr_gps : sensor_msgs.msg._NavSatFix.NavSatFix The gps point recieved from ROS Topic """ self.curr = curr_gps rospy.loginfo("******************") self._curr_lat = self.curr.latitude self._curr_lon = self.curr.longitude if (math.isnan(self.curr.latitude) == False): self._curr_UTMx, self._curr_UTMy, _, _ = utm.from_latlon( self._curr_lat, self._curr_lon) dist = self.calc_distance((self._curr_UTMx, self._curr_UTMy), (self._old_UTMx, self._old_UTMy)) rospy.loginfo("Distance travelled: %f" % dist) if self.first_time_flag == 1: rospy.loginfo("Generating local_map") self._curr_point = (self._curr_UTMy, self._curr_UTMx) self._old_UTMx = self._curr_UTMx self._old_UTMy = self._curr_UTMy self.curr_gps_point = (self._curr_lat, self._curr_lon) north, south, east, west = ox.bbox_from_point( self.curr_gps_point, distance=rospy.get_param("grid_map_size")) url_name = self.url_base + str(west) + "," + str( south) + "," + str(east) + "," + str(north) rospy.loginfo("downloading ...") urllib.urlretrieve(url_name, self.file_path_local_map + 'local_map.xml') self.first_time_flag = 0 if dist > self.map_load_range: rospy.loginfo("Generating local_map") self._curr_point = (self._curr_UTMy, self._curr_UTMx) self._old_UTMx = self._curr_UTMx self._old_UTMy = self._curr_UTMy self.curr_gps_point = (self._curr_lat, self._curr_lon) north, south, east, west = ox.bbox_from_point( self.curr_gps_point, distance=rospy.get_param("grid_map_size")) url_name = self.url_base + str(west) + "%2C" + str( south) + "%2C" + str(east) + "%2C" + str(north) rospy.loginfo("downloading ...") urllib.urlretrieve(url_name, self.file_path_local_map + 'local_map.xml') else: rospy.loginfo("distance is less than %f meters" % self.map_load_range) else: rospy.loginfo("gps value is not a number ...")
# create network from point, inside bounding box of N, S, E, W each 750m from point G2 = ox.graph_from_point(location_point, distance=5000, distance_type='bbox', network_type='drive') G2 = ox.project_graph(G2) fig, ax = ox.plot_graph(G2, node_size=30, node_color='#66cc66') import osmnx as ox, geopandas as gpd ox.config(log_file=True, log_console=True, use_cache=True) location_point = (-17.1010286, 145.7753749) gdf = ox.buildings_from_point(point=location_point, distance=5000) gdf_proj = ox.project_gdf(gdf) bbox = ox.bbox_from_point(point=location_point, distance=5000, project_utm=True) fig, ax = ox.plot_buildings(gdf_proj) import osmnx as ox, geopandas as gpd ox.config(log_file=True, log_console=True, use_cache=True) place_names = ['Gordonvale, Queensland, Australia'] east_bay = ox.gdf_from_places(place_names) ox.save_gdf_shapefile(east_bay) east_bay = ox.project_gdf(east_bay) fig, ax = ox.plot_shape(east_bay) import osmnx as ox ox.config(log_file=True, log_console=True, use_cache=True) city = ox.gdf_from_place('Sydney, New South Wales, Australia')
def plot_camera( camera, bbox_side=100, show_camera=True, camera_color="#FFFFFF", camera_marker="*", camera_markersize=10, annotate_camera=True, draw_radius=False, # fig_height=6, fig_width=None, margin=0.02, bgcolor='k', node_color='#999999', node_edgecolor='none', node_zorder=2, node_size=50, node_alpha=1, edge_color='#555555', edge_linewidth=1.5, edge_alpha=1, # probability_cmap=plt.cm.Oranges, show_colorbar_label=True, draw_colorbar=True, draw_arrow=False, # color_near_nodes=True, color_candidate_edges=True, nn_color='#66B3BA', nedge_color='#D0CE7C', labels_color="white", annotate_nn_id=False, annotate_nn_distance=True, adjust_text=True, # save=False, file_format='png', filename=None, dpi=300): """ Plot the camera on a networkx spatial graph. Parameters ---------- bbox_side : int half the length of one side of the bbox (a square) in which to plot the camera. This value should usually be kept within small scales (hundreds of meters), otherwise near nodes and candidate edges become imperceptible. camera_color : string the color of the point representing the location of the camera camera_marker : string marker used to represent the camera camera_markersize: int the size of the marker representing the camera annotate_camera : True whether to annotate the camera or not using its id draw_radius : bool whether to draw (kind of) a circle representing the range of the camera bgcolor : string the background color of the figure and axis - passed to osmnx's plot_graph node_color : string the color of the nodes - passed to osmnx's plot_graph node_edgecolor : string the color of the node's marker's border - passed to osmnx's plot_graph node_zorder : int zorder to plot nodes, edges are always 2, so make node_zorder 1 to plot nodes beneath them or 3 to plot nodes atop them - passed to osmnx's plot_graph node_size : int the size of the nodes - passed to osmnx's plot_graph node_alpha : float the opacity of the nodes - passed to osmnx's plot_graph edge_color : string the color of the edges' lines - passed to osmnx's plot_graph edge_linewidth : float the width of the edges' lines - passed to osmnx's plot_graph edge_alpha : float the opacity of the edges' lines - passed to osmnx's plot_graph probability_cmap : matplotlib colormap Colormap used to color candidate edges by probability of observation. show_colorbar_label : bool whether to set the label of the colorbar or not draw_colorbar : bool whether to plot a colorbar as a legend for probability_cmap nn_color : string the color of near nodes - these are not necessarily in range of the camera, but they are part of edges that do nedge_color : string the color of candidate edges - nearby edges filtered by address or other condition labels_color : string the color of labels used to annotate nearby nodes annotate_nn_id : bool whether the text annotating near nodes should include their id annotate_nn_distance : bool whether the text annotating near nodes should include their distance from the camera adjust_text : bool whether to optimise the location of the annotations, using adjustText.adjust_text, so that overlaps are avoided. Notice that this incurs considerable computational cost. Turning this feature off will result in much faster plotting. save : bool whether to save the figure in the app folder's images directory file_format : string format of the image filename : string filename of the figure to be saved. The default value is the camera's id. dpi : int resolution of the image Returns ------- fig, ax : tuple """ if filename is None: filename = camera.id bbox = ox.bbox_from_point(point=camera.point, distance=bbox_side) # Set color of near nodes by index nodes_colors = [node_color] * len(camera.network.nodes()) if color_near_nodes: i = 0 for node in camera.network.nodes(data=False): if node in camera.lsystem['nnodes']: nodes_colors[i] = nn_color i = i + 1 # Color near edges edges_colors = [edge_color] * len(camera.network.edges()) if color_candidate_edges: norm = colors.Normalize(vmin=0, vmax=1) cmap = plt.cm.ScalarMappable(norm=norm, cmap=probability_cmap) pcolor = {edge: cmap.to_rgba(p) for edge, p in camera.p_cedges.items()} j = 0 for u, v, k in camera.network.edges(keys=True, data=False): edge = Edge(u, v, k) if edge in camera.lsystem['cedges']: edges_colors[j] = pcolor[edge] j = j + 1 # Plot it fig, axis = \ ox.plot_graph( camera.network, bbox = bbox, margin = margin, bgcolor = bgcolor, node_color = nodes_colors, node_edgecolor = node_edgecolor, node_zorder = node_zorder, edge_color = edges_colors, node_alpha = node_alpha, edge_linewidth = edge_linewidth, edge_alpha = edge_alpha, node_size = node_size, save = False, show = False, close = False, axis_off = True, fig_height = fig_height, fig_width = fig_width) if draw_colorbar: axis2 = fig.add_axes([0.3, 0.15, 0.15, 0.02]) cb = colorbar.ColorbarBase(axis2, cmap=probability_cmap, norm=norm, orientation='horizontal') cb.set_ticks([0, 0.2, 0.4, 0.6, 0.8, 1.0]) if show_colorbar_label: cb.set_label("Probability of edge", color=labels_color, size=9) cb.ax.xaxis.set_tick_params(pad=0, color=labels_color, labelcolor=labels_color, labelsize=8) # Plot Camera if show_camera: camera_point = axis.plot(camera.point.lng, camera.point.lat, marker=camera_marker, color=camera_color, markersize=camera_markersize) if show_camera and draw_radius: radius_circle = \ plt.Circle((camera.point.lng, camera.point.lat), radius = camera.radius/deg2distance(unit = Units.m), color=camera_color, fill=False) axis.add_artist(radius_circle) if show_camera and annotate_camera: camera_text = axis.annotate(str(camera.id), xy=(camera.point.lng, camera.point.lat), color=labels_color) if draw_arrow: base_x = camera.network.nodes[camera.edge.u]['x'] base_y = camera.network.nodes[camera.edge.u]['y'] end_x = camera.network.nodes[camera.edge.v]['x'] end_y = camera.network.nodes[camera.edge.v]['y'] color = pcolor[camera.edge] axis.annotate('', xytext=(base_x, base_y), xy=(end_x, end_y), arrowprops=dict(arrowstyle="->", color=color), size=15) if color_near_nodes and (annotate_nn_id or annotate_nn_distance): # Annotate nearest_neighbors texts = [] for id in camera.lsystem['nnodes']: distance_x = camera.lsystem['lnodes'][id][0] distance_y = camera.lsystem['lnodes'][id][1] distance = math.sqrt(distance_x**2 + distance_y**2) if distance < bbox_side: s1 = "" s2 = "" if annotate_nn_id: s1 = "{}: ".format(id) if annotate_nn_distance: s2 = "{:,.1f}m".format(distance) text = axis.text(camera.network.node[id]['x'], camera.network.node[id]['y'], s=s1 + s2, color=labels_color) texts.append(text) if show_camera and annotate_camera: texts.append(camera_text) if adjust_text: additional_obj = [] if draw_radius: additional_obj.append(radius_circle) if annotate_camera: additional_obj.append(camera_text) adjustText.adjust_text(texts, x=[ camera.network.node[id]['x'] for id in camera.lsystem['nnodes'] ], y=[ camera.network.node[id]['y'] for id in camera.lsystem['nnodes'] ], ax=axis, add_objects=camera_point + additional_obj, force_points=(0.5, 0.6), expand_text=(1.2, 1.4), expand_points=(1.4, 1.4)) if save: save_fig(fig, axis, filename, file_format, dpi) return fig, axis
def get_map(self, start_lat, start_long, end_lat, end_long, chosen_weight): print( "Coordinates", start_lat, start_long, end_lat, end_long, ) print("weight", chosen_weight) place = 'Amherst' place_query = { 'city': 'Amherst', 'state': 'Massachusetts', 'country': 'USA' } G = ox.graph_from_place(place_query, network_type='drive') G = ox.add_node_elevations( G, api_key='AIzaSyB9DBYn2sdIznFbmBg4DHOTl54soDBkx2E') G = ox.add_edge_grades(G) edge_grades = [ data['grade_abs'] for u, v, k, data in ox.get_undirected(G).edges(keys=True, data=True) ] avg_grade = np.mean(edge_grades) #print('Average street grade in {} is {:.1f}%'.format(place, avg_grade*100)) if chosen_weight == 0: choice = 'length' elif chosen_weight == 1: choice = 'minimum' elif chosen_weight == 2: choice = 'impedence' med_grade = np.median(edge_grades) #print('Median street grade in {} is {:.1f}%'.format(place, med_grade*100)) # project the street network to UTM G_proj = ox.project_graph(G) # get one color for each node, by elevation, then plot the network #nc = ox.get_node_colors_by_attr(G_proj, 'elevation', cmap='plasma', num_bins=20) #fig, ax = ox.plot_graph(G_proj, fig_height=6, node_color=nc, node_size=12, node_zorder=2, edge_color='#dddddd') # get a color for each edge, by grade, then plot the network #ec = ox.get_edge_colors_by_attr(G_proj, 'grade_abs', cmap='plasma', num_bins=10) #fig, ax = ox.plot_graph(G_proj, fig_height=6, edge_color=ec, edge_linewidth=0.8, node_size=0) # select an origin and destination node and a bounding box around them origin = ox.get_nearest_node(G, (start_lat, start_long)) destination = ox.get_nearest_node(G, (end_lat, end_long)) bbox = ox.bbox_from_point( ((start_lat + end_lat) / 2, (start_long + end_long) / 2), distance=5000, project_utm=True) for u, v, k, data in G_proj.edges(keys=True, data=True): data['impedance'] = self.impedance(data['length'], data['grade_abs']) data['rise'] = data['length'] * data['grade'] #weight_choice = {'easy' : 'length', 'median' : 'minimum', 'hard' : 'impedance'} routef = nx.shortest_path(G_proj, source=origin, target=destination, weight=choice) route_map = ox.plot_route_folium(G, routef) p1 = [start_lat, start_long] p2 = [end_lat, end_long] folium.Marker(location=p1, icon=folium.Icon(color='green')).add_to(route_map) folium.Marker(location=p2, icon=folium.Icon(color='red')).add_to(route_map) print("------------------4321") result = self.print_route_stats(routef, G_proj) filepath = 'routeff.html' route_map.save(filepath) IFrame(filepath, width=600, height=500) return result
def animate_camera( camera, bbox_side=100, camera_color="#FFFFFF", camera_marker="*", camera_markersize=10, annotate_camera=True, draw_radius=False, # fig_height=9, fig_width=9, margin=0.02, bgcolor='k', node_color='#999999', node_edgecolor='none', node_zorder=2, node_size=50, node_alpha=1, edge_color='#555555', edge_linewidth=1.5, edge_alpha=1, labels_fontsize=8, # probability_cmap=plt.cm.Oranges, show_colorbar_label=True, draw_colorbar=True, # nn_color='#66B3BA', nedge_color='#D0CE7C', labels_color="white", annotate_nn_id=False, annotate_nn_distance=True, adjust_text=True, # save_as='mp4', filename=None, dpi=320, # time_per_scene=5000, # ms time_per_frame=250, # ms progress=True, colorbar_rect=[0.125, 0.20, 0.20, 0.02], colorbar_ticks_fontsize=6, show_subtitle=True, subtitle_placement=(0.00, 0.05), subtitle_fontsize=12, sample_point_size=4, sample_valid_color="green", sample_invalid_color="red"): """ Generate an animation explaining the edge estimation procedure for the camera on a networkx spatial graph. The generated animation is not Total number of scenes, in the animation, is 6 + number of candidate edges. Parameters ---------- bbox_side : int half the length of one side of the bbox (a square) in which to plot the camera. This value should usually be kept within small scales (hundreds of meters), otherwise near nodes and candidate edges become imperceptible. camera_color : string the color of the point representing the location of the camera camera_marker : string marker used to represent the camera camera_markersize: int the size of the marker representing the camera annotate_camera : True whether to annotate the camera or not using its id draw_radius : bool whether to draw (kind of) a circle representing the range of the camera bgcolor : string the background color of the figure and axis - passed to osmnx's plot_graph node_color : string the color of the nodes - passed to osmnx's plot_graph node_edgecolor : string the color of the node's marker's border - passed to osmnx's plot_graph node_zorder : int zorder to plot nodes, edges are always 2, so make node_zorder 1 to plot nodes beneath them or 3 to plot nodes atop them - passed to osmnx's plot_graph node_size : int the size of the nodes - passed to osmnx's plot_graph node_alpha : float the opacity of the nodes - passed to osmnx's plot_graph edge_color : string the color of the edges' lines - passed to osmnx's plot_graph edge_linewidth : float the width of the edges' lines - passed to osmnx's plot_graph edge_alpha : float the opacity of the edges' lines - passed to osmnx's plot_graph probability_cmap : matplotlib colormap Colormap used to color candidate edges by probability of observation. show_colorbar_label : bool whether to set the label of the colorbar or not draw_colorbar : bool whether to plot a colorbar as a legend for probability_cmap nn_color : string the color of near nodes - these are not necessarily in range of the camera, but they are part of edges that do nedge_color : string the color of candidate edges - nearby edges filtered by address or other condition labels_color : string the color of labels used to annotate nearby nodes annotate_nn_id : bool whether the text annotating near nodes should include their id annotate_nn_distance : bool whether the text annotating near nodes should include their distance from the camera adjust_text : bool whether to optimise the location of the annotations, using adjustText.adjust_text, so that overlaps are avoided. Notice that this incurs considerable computational cost. Turning this feature off will result in much faster plotting. save_as : string format in which to save the animation in the app folder's images directory. Choose 'mp4' to save the animation in mp4 format, using ffmpeg, 'gif' to save the animation in gif format, using imagemagick, or any other value to skip saving the animation. filename : string filename of the figure to be saved. The default value is the camera's id. dpi : int resolution of the image, if saving the animation in 'mp4' format. time_per_scene : int time per scene in milliseconds time_per_frame : int time per frame in milliseconds. If time_per_scene = 250, then each scene has 20 frames. Most scenes just repeat the same frame, except the scenes for candidate edges - which plot a new sampled point per frame. progress : bool if True then a bar will show the current progress of generating the animation. colorbar_rect : list rectangle position of the colorbar as used by matplotlib.figure.add_axes labels_fontsize : int fontsize of generic text labels (nodes, camera, colorbar) colorbar_ticks_fontsize : int fontsize of colorbar ticks text show_subtitle : bool if True show a text box explaining each scene subtitle_placement : tuple (x,y) coordinates, in transformed axis, of where to place the subtitle text subtitle_fontsize : int fontsize of subtitle text sample_point_size : int marker size of points sampled in candidate edges sample_point_valid_color : string color of sample points, in candidate edges, that fit the criteria: < camera.radius and < camera.max_angle sample_invalid_color : string color of sample points, in candidate edges, that don't fit the criteria: < camera.radius and < camera.max_angle Returns ------- anim : FuncAnimation """ start_time = time.time() # ---------------------------- # Generate base fig # ---------------------------- bbox = ox.bbox_from_point(point=camera.point, distance=bbox_side) fig, axis = ox.plot_graph(camera.network, bbox=bbox, margin=margin, bgcolor=bgcolor, node_color=node_color, node_edgecolor=node_edgecolor, node_zorder=node_zorder, edge_color=edge_color, node_alpha=node_alpha, edge_linewidth=edge_linewidth, edge_alpha=edge_alpha, node_size=node_size, save=False, show=False, close=False, axis_off=True, fig_height=fig_height, fig_width=fig_width) # ---------------------------- # Compute colors # ---------------------------- nodes_colors = [node_color] * len(camera.network.nodes()) i = 0 for node in camera.network.nodes(data=False): if node in camera.lsystem['nnodes']: nodes_colors[i] = nn_color i = i + 1 # Color near edges edges_colors = [edge_color] * len(camera.network.edges()) norm = colors.Normalize(vmin=0, vmax=1) cmap = plt.cm.ScalarMappable(norm=norm, cmap=probability_cmap) pcolor = {edge: cmap.to_rgba(p) for edge, p in camera.p_cedges.items()} j = 0 for u, v, k in camera.network.edges(keys=True, data=False): edge = Edge(u, v, k) if edge in camera.lsystem['cedges']: edges_colors[j] = pcolor[edge] j = j + 1 # ---------------------------- # Plot camera point # Compute texts but disable them # ---------------------------- texts = [] camera_point = axis.plot(camera.point.lng, camera.point.lat, marker=camera_marker, color=bgcolor, markersize=camera_markersize) camera_text = axis.annotate(str(camera.id), xy=(camera.point.lng, camera.point.lat), color=labels_color, fontsize=labels_fontsize) texts.append(camera_text) # Nearest Neighbors for id in camera.lsystem['nnodes']: distance_x = camera.lsystem['lnodes'][id][0] distance_y = camera.lsystem['lnodes'][id][1] distance = math.sqrt(distance_x**2 + distance_y**2) if distance < bbox_side: s1 = "" s2 = "" if annotate_nn_id: s1 = "{}: ".format(id) if annotate_nn_distance: s2 = "{:,.1f}m".format(distance) text = axis.text(camera.network.node[id]['x'], camera.network.node[id]['y'], s=s1 + s2, color=labels_color, fontsize=labels_fontsize) texts.append(text) if adjust_text: additional_obj = [] if draw_radius: additional_obj.append(radius_circle) if annotate_camera: additional_obj.append(camera_text) adjustText.adjust_text(texts, x=[ camera.network.node[id]['x'] for id in camera.lsystem['nnodes'] ], y=[ camera.network.node[id]['y'] for id in camera.lsystem['nnodes'] ], ax=axis, add_objects=camera_point + additional_obj, force_points=(0.5, 0.6), expand_text=(1.2, 1.4), expand_points=(1.4, 1.4)) axis.texts = [] # Not elegant at all -> think of better one in the future uedges = [ frozenset((cedge.u, cedge.v)) for cedge in camera.lsystem['cedges'] ] unique_uedges = list(set(uedges)) # ---------------------------- # Frame and time calculations # ---------------------------- frames_per_scene = int(time_per_scene / time_per_frame) scene_names = [ 'network_only', 'camera', 'near_nodes'] + \ [ 'near_edges,{}'.format(id) for id in range(len(unique_uedges)) ] + \ ['ne_pause', 'colorbar', 'chosen_edge'] scenes = np.repeat(scene_names, frames_per_scene) scene_frame_index = np.stack(np.unravel_index( np.ravel_multi_index([list(range(len(scenes)))], scenes.shape), (len(scene_names), frames_per_scene)), axis=1) # ---------------------------- # Get sampled points per edge # ---------------------------- _, _, samples = estimate_camera_edge( camera.network, camera.lsystem, nsamples=frames_per_scene, radius=camera.radius, max_angle=camera.max_angle, left_handed_traffic=camera.left_handed_traffic, return_samples=True) # ---------------------------- # Get sampled points per edge # ---------------------------- if show_subtitle: subtitle = \ axis.text(subtitle_placement[0], subtitle_placement[1], '', color = bgcolor, transform = axis.transAxes, fontsize = subtitle_fontsize, verticalalignment = 'center', bbox = dict(boxstyle = 'round', facecolor = labels_color, alpha = 0.5), wrap = False, family = "serif") log("Attempting to animate camera '{}' with {} undirected candidate edges: {} scenes, {} frames"\ .format(camera.id, len(unique_uedges), len(scene_names), len(scenes)), level = lg.INFO) if progress: bar = Bar('Animating as {}'.format(save_as), max=len(scenes) + 1) # ---------------------------- # Animate function # ---------------------------- def update(frame): scene = scenes[frame] relative_frame = scene_frame_index[frame][1] if progress: bar.next() if scene == 'network_only': if relative_frame == 0: txtstr = """ This is a graph modelling the road network centered at the camera, using a bounding box, with length/2 = {} meters. Nodes and edges represent junctions and roads, respectively."""\ .format(bbox_side) elif scene == 'camera': if relative_frame == 0: # Small Cheat, because of adjustText - is there a better solution? camera_point[0].set_color(camera_color) axis.texts += [texts[0]] txtstr = """ The camera, with id '{}', has a maximum range of {} meters, and a maximum angle of {} degrees (on the horizontal plane to the plate number)"""\ .format(camera.id, camera.radius, camera.max_angle) elif scene == 'near_nodes': if relative_frame == 0: axis.collections[1].set_color(nodes_colors) axis.texts += texts[1:] txtstr = """ The goal is to determine which road (graph edge) the camera is pointing at. We start by finding, the nodes which are in range of the camera, and the neighbors (of degree 1) of these.""" elif scene.startswith('near_edges'): # Not elegant at all -> think of better one in the future unique_uedge_id = int(scene.split(',')[1]) unique_uedge = unique_uedges[unique_uedge_id] cedge_id = uedges.index(unique_uedge) sample = samples[camera.lsystem['cedges'] [cedge_id]][0][relative_frame] isvalid = samples[camera.lsystem['cedges'] [cedge_id]][1][relative_frame] if isvalid: color = sample_valid_color else: color = sample_invalid_color point = from_lvector(origin=camera.point, lvector=sample) log("Edge {}, id = {}. sample = {}, isvalid = {}, point = {}"\ .format(unique_uedge_id, relative_frame, sample, isvalid, point), level = lg.DEBUG) sample_point = axis.plot(point.lng, point.lat, marker='o', color=color, markersize=sample_point_size) txtstr = """ The edges between these pairs of nodes considered candidate edges. We sample points from each candidate edge - {} - and calculate its distance and angle to the camera. Points are coloured in {} or {}, if the distance and angle to the camera are below the maximum value or not."""\ .format(unique_uedge_id, sample_valid_color, sample_invalid_color) elif scene == 'colorbar': if relative_frame == 0: # Remove sampled points axis.lines = [axis.lines[0]] axis.collections[0].set_color(edges_colors) axis2 = fig.add_axes(colorbar_rect) cb = colorbar.ColorbarBase(axis2, cmap=probability_cmap, norm=norm, orientation='horizontal') cb.set_ticks([0, 0.2, 0.4, 0.6, 0.8, 1.0]) cb.set_label("Proportion of valid points", color=labels_color, size=labels_fontsize) cb.ax.xaxis.set_tick_params(pad=0, color=labels_color, labelcolor=labels_color, labelsize=colorbar_ticks_fontsize) txtstr = """ We then calculate the proportion of points that fit these criteria, and pick the undirected edge that maximises this value."""\ .format(camera.radius, camera.max_angle) elif scene == 'chosen_edge': if relative_frame == 0: axis.collections[0].set_color(edge_color) base_x = camera.network.nodes[camera.edge.u]['x'] base_y = camera.network.nodes[camera.edge.u]['y'] end_x = camera.network.nodes[camera.edge.v]['x'] end_y = camera.network.nodes[camera.edge.v]['y'] color = pcolor[camera.edge] axis.annotate('', xytext=(base_x, base_y), xy=(end_x, end_y), arrowprops=dict(arrowstyle="->", color=color, linewidth=edge_linewidth), size=15) txtstr = """ Finally, we pick the directed edge that represents traffic moving in the nearest of the two lanes (avoiding crossing traffic in the camera's frame). This depends on whether the traffic system is left or right-handed. In this case it is: {}."""\ .format("left-handed" if camera.left_handed_traffic else "right_handed") else: return if relative_frame == 0 and show_subtitle: txt = textwrap.dedent(txtstr)[1:] subtitle.set_text(txt) # ---------------------------- # Animate it! # ---------------------------- anim = animation.FuncAnimation(fig, update, blit=False, frames=len(scenes), interval=time_per_frame, repeat=False) if filename is None: filename = camera.id savefig_kwargs = { 'facecolor': bgcolor, 'frameon': False, 'bbox_inches': 'tight', 'pad_inches': 0 } if save_as == 'mp4': filepath = os.path.join(settings['app_folder'], settings['images_folder_name'], "{}.mp4".format(filename)) anim.save(filepath, dpi=dpi, savefig_kwargs=savefig_kwargs) if progress: bar.finish() elif save_as == 'gif': filepath = os.path.join(settings['app_folder'], settings['images_folder_name'], "{}.gif".format(filename)) anim.save(filepath, writer='imagemagick', fps=1000 / time_per_frame, savefig_kwargs=savefig_kwargs) if progress: bar.finish() log("Animated camera in {:,.3f} seconds {}"\ .format(time.time() - start_time, "and saved it to file {}".format(filepath) if save_as in {'mp4', 'gif'} else "but did not save it to file"), level = lg.INFO) return anim