def test_gdf_shapefiles(): # test loading spatial boundaries, saving as shapefile, and plotting city = ox.gdf_from_place('Manhattan, New York City, New York, USA') city_projected = ox.project_gdf(city, to_crs={'init':'epsg:3395'}) ox.save_gdf_shapefile(city_projected) city = ox.gdf_from_place('Manhattan, New York City, New York, USA', buffer_dist=100) ox.plot_shape(city)
def create_buffer_geopandas(geoJsonFileName, bufferDistanceMeters=2, bufferRoundness=1, projectToUTM=True): ''' Create a buffer around the lines of the geojson. Return a geodataframe. ''' if os.stat(geoJsonFileName).st_size == 0: return [] inGDF = gpd.read_file(geoJsonFileName) # set a few columns that we will need later inGDF['type'] = inGDF['road_type'].values inGDF['class'] = 'highway' inGDF['highway'] = 'highway' if len(inGDF) == 0: return [] # Transform gdf Roadlines into UTM so that Buffer makes sense if projectToUTM: tmpGDF = ox.project_gdf(inGDF) else: tmpGDF = inGDF gdf_utm_buffer = tmpGDF # perform Buffer to produce polygons from Line Segments gdf_utm_buffer['geometry'] = tmpGDF.buffer(bufferDistanceMeters, bufferRoundness) gdf_utm_dissolve = gdf_utm_buffer.dissolve(by='class') gdf_utm_dissolve.crs = gdf_utm_buffer.crs if projectToUTM: gdf_buffer = gdf_utm_dissolve.to_crs(inGDF.crs) else: gdf_buffer = gdf_utm_dissolve return gdf_buffer
#indir = "data/vector/city_boundaries/" for city in cities: name = os.path.basename(city).split('.')[0] place = gpd.read_file(city) place_simple = place.unary_union # disolving boundaries based on attributes # Use retain_all if you want to keep all disconnected subgraphs (e.g. when your places aren't adjacent) G = ox.graph_from_polygon(place_simple, network_type='drive', retain_all=True) G_projected = ox.project_graph(G) # save the shapefile to disk #name = os.path.basename("beijing.shp")).split(".")[0] # make better place_names ox.save_graph_shapefile(G_projected, filename=name) area = ox.project_gdf(place).unary_union.area stats = ox.basic_stats(G, area=area) # save to file: def ensure_dir(file_path): directory = os.path.dirname(file_path) if not os.path.exists(directory): os.makedirs(directory) path = os.path.join('data/vector/city_networks/', name) ensure_dir(path) with open(path + '_stats.json', 'wb') as f: json.dump(stats, f)
os.makedirs(directory) for place in places: name = (place.replace(",","").replace(" ","")) # make better place_names print('working on: ', name) #make a geodataframe of the street network (outline) from openstreetmap place names # use retain_all if you want to keep all disconnected subgraphs (e.g. when your places aren't adjacent) G = ox.graph_from_place(place, network_type='drive', retain_all=True) G = ox.project_graph(G) #make a geodataframe of the shape (outline) from openstreetmap place names gdf = ox.gdf_from_place(place) gdf = ox.project_gdf(gdf) ox.save_graph_shapefile(G, filename=name) print(name, ' has crs:' ) gdf.to_crs({'init': 'epsg:3395'}) # Confirm big step of projection change # calculate basic stats for the shape # TODO adjust this to calculate stats based on neighborhoods stats = ox.basic_stats(G, area=gdf['geometry'].area[0]) print('area', gdf['area'][0] / 10**6, 'sqkm') # save to file: def ensure_dir(file_path): directory = os.path.dirname(file_path)
def test_geocode_to_gdf(): # test loading spatial boundaries and plotting city = ox.geocode_to_gdf(place1, which_result=1, buffer_dist=100) city_projected = ox.project_gdf(city, to_crs="epsg:3395")
def create_intersections_bigdb_by_city(data): """This function creates a database of the coordinates and streets of all intersections in a mile radius of a given zipcode. Currently set to drive network and a radius of 1610m (1 mile). Edit the parameters in line 81 to fit your preferences""" d = data[1] zipcode = d[1] city = d[2] state = d[3] county = d[4] tablename = "intersections_" + str(city) try: cur.execute( "CREATE TABLE " + tablename + " (zip_code TEXT, city TEXT, state TEXT, county TEXT, latlon_str TEXT, streetnames_str TEXT);" ) latlon_array = [] streetname_array = [] latlon_array_str = "" streetname_array_str = "" try: place = city + ', ' + county + ', ' + state + ", USA " G = ox.graph_from_place(place, network_type='drive', distance=1610, retain_all=True, simplify=True) G_proj = ox.project_graph(G) # clean up the intersections and extract their xy coords intersections = ox.clean_intersections(G_proj, tolerance=15, dead_ends=False) # points = np.array([point.xy for point in intersections]) gdf = gpd.GeoDataFrame(geometry=intersections) gdf.crs = G_proj.graph['crs'] lonlat = ox.project_gdf(gdf, to_latlong=True) a = lonlat['geometry'].tolist() for coord in a: lon = coord.x lat = coord.y latlon_tuple = (lat, lon) nearest_streets = get_nearest_streetnames(latlon_tuple) streetname_array.append(nearest_streets) latlon_array.append(latlon_tuple) except: #THROW A WARNING THAT THERE IS NO LAT/LON DATA FOR THIS ZIPCODE pass latlon_array_str = str(latlon_array).strip('[]') streetname_array_str = str(streetname_array).strip('[]') to_db = [zipcode, city, state, county, latlon_array_str] cmd = "INSERT INTO " + tablename + " (zip_code, city, state, county,latlon_str, streetname_array_str) VALUES (?, ?, ?, ?, ?, ?);" cur.execute(cmd, to_db) for row in cur.execute("SELECT * from " + tablename): print(row) except: print(tablename + " already exists")
import shp2osmnx as s2nx import csv Polygon_layer = '{}'.format(Polygon_layer) Polygon_in_crs = '{}'.format(Polygon_in_crs) Folder_to_load_from = '{}'.format(Folder_to_load_from) Folder_to_save_graphs = str(Folder_to_save_graphs) Name_of_stat_file = '{}'.format(Name_of_stat_file) #Creating geodataframe from polygon shapefile Poly_area = s2nx.gdf_from_shapefile(Polygon_layer, in_crs=Polygon_in_crs, buffer_dist=Buffer_around_polygon) #calulate the area of the a area = ox.project_gdf(Poly_area).unary_union.area print area #create graph G = ox.save_load.load_graphml(Graphml_File_Name, folder=Folder_to_load_from) #Calculate the basic stats stats = ox.basic_stats(G, area=area) stats['area'] = area #statsfile=Graphml_File_Name+str('/centrality.csv') filepath = Folder_to_save_graphs + '/' + Name_of_stat_file df = pd.DataFrame.from_dict(stats) df.to_csv(filepath)
import osmnx # configure logging/caching osmnx.config(log_console=True, use_cache=True) # configure the image display size = 256 # load buildings from about 1.5km² around UCL point = (51.524498, -0.133874) dist = 612 gdf = osmnx.buildings_from_point(point=point, distance=dist) # preview image gdf_proj = osmnx.project_gdf(gdf, to_crs={'init': 'epsg:3857'}) fig, ax = osmnx.plot_buildings(gdf_proj, bgcolor='#333333', color='w', figsize=(4, 4), save=True, show=False, close=True, filename='test_buildings_preview', dpi=600) # save test_dir = os.path.dirname(__file__) test_data_geojson = str(os.path.join(test_dir, 'test_buildings.geojson')) subprocess.run(["rm", test_data_geojson])
def make_plot(place, point, network_type='drive', bldg_color='orange', dpi=250,dist=1000, default_width=4, street_widths=None): gdf=ox.buildings_from_point(point=point, distance=dist) gdf_proj=ox.project_gdf(gdf) fig, ax=ox.plot_figure_ground(point=point, dist=dist, network_type=network_type, default_width=default_width,street_widths=None, save=False, show=False, close=True) fig, ax=ox.plot_buildings(gdf_proj, fig=fig, ax=ax, color=bldg_color, set_bounds=False,save=True, show=False, close=True, filename=place, dpi=dpi)
roadlayer.set_ylim(ymin, ymax) buildingslayer = BuildingsGDF.plot( ax=roadlayer, column='bouwjaar', cmap= 'brg', #see https://matplotlib.org/3.1.0/tutorials/colors/colormaps.html legend=True, legend_kwds={ 'label': "Construction year", 'orientation': "vertical" }) plt.savefig('./output/WURcampusMapBuildings.png') import osmnx as ox city = ox.geocoder.geocode_to_gdf('Wageningen, Netherlands') ox.plot.plot_footprints(ox.project_gdf(city)) WageningenRoadsGraph = ox.graph.graph_from_place('Wageningen, Netherlands', network_type='bike') ox.plot.plot_graph(WageningenRoadsGraph, figsize=(10, 10), node_size=2) ox.io.save_graph_shapefile(G=WageningenRoadsGraph, filepath='OSMnetwork_Wageningen.shp') gdf_nodes, gdf_edges = ox.graph_to_gdfs(G=WageningenRoadsGraph) print(gdf_nodes.info()) print(gdf_edges.info()) source = ox.distance.get_nearest_node(WageningenRoadsGraph, (51.987817, 5.665779)) target = ox.distance.get_nearest_node(WageningenRoadsGraph, (51.964870, 5.662409)) shortestroute = ox.distance.shortest_path(G=WageningenRoadsGraph, orig=source,
################################################################################ # OSMnx tests # Playing around with OSMnx # HMSC ################################################################################ #Load package ################# import osmnx as ox, geopandas as gpd ox.config(log_file=True, log_console=True, use_cache=True) # Parameters ################## location_point = (-17.1010286, 145.7753749) # Gordonvale location_point = (-16, 8122246, 145.7183589) # Yorkey's Knob location_point = (-11.71654, 43.42988) # Comoros distance = 5000 # Roads ####################### 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') # Buildings ################### gdf = ox.buildings_from_point(point=location_point, distance=distance) gdf_proj = ox.project_gdf(gdf) bbox = ox.bbox_from_point(point=location_point, distance=distance, project_utm=True) fig, ax = ox.plot_buildings(gdf_proj, show=True)
def plot(self, x=None, size=9, name='temp_image', network_type='walk', dpi=90, default_width=5, street_widths=None): """ plot the map Parameters - x(model.x): default None, variables x after optimization size(int) : default 9 name(string) : default 'temp_image', the saved image name network_type(string) : default walk dpi(int) : default 90 default_width(int) : default 5 street_widths(int) : default None """ # default color set - before optimization ec = [] for i in self.gdf.index: # white color for vacant houses if self.gdf['housetype'][i] == 2: ec.append('w') # yellow color for police station elif self.gdf['amenity'][i] == 'police': ec.append('yellow') # light green for curch elif self.gdf['amenity'][i] == 'place_of_worship': ec.append('#d7ff6e') # red color for non structure elif self.gdf['building'][i] != 'yes': ec.append('r') # #ff6060 for area > 398 elif (pd.isnull(self.gdf['addr:street'][i]) and self.gdf_proj.area[i] > 398) or self.gdf_proj.area[i] > 398: ec.append('#ff6060') # #8e8e8e for no address elif pd.isnull(self.gdf['addr:street'][i]): ec.append('#8e8e8e') # #ffcf77 for renter houses elif self.gdf['housetype'][i] == 0: ec.append('#ffcf77') # #ffcf77 for owner houses elif self.gdf['housetype'][i] == 1: ec.append('orange') # blue coloe fo o.w., which means the model is not correct else: ec.append('blue') # plot the original map before optimization if x == None: #ox.plot_buildings(self.gdf, figsize = (size,size) ,color = ec, bgcolor = "aliceblue") # get gdf_proj gdf_proj = ox.project_gdf(self.gdf) # initial figure ground fig, ax = ox.plot_figure_ground(address=self.address, dist=self.radius, network_type=network_type, default_width=default_width, bgcolor='#333333', edge_color='w', street_widths=street_widths, save=False, show=False, close=True, fig_length=size) # plot the building fig, ax = ox.plot_buildings(gdf_proj, fig=fig, ax=ax, color=ec, set_bounds=True, save=True, show=False, close=True, filename=name, dpi=dpi) # save image Image('{}/{}.{}'.format(img_folder, name, extension), height=image_size, width=image_size) return fig, ax # after optimization else: # update color set # if x == 1 or very close to 1 (tolerance) ec_after = [ 'mediumseagreen' if x[self.Houses[i]].X == 1.0 or abs(x[self.Houses[i]].X - 1.0) < 0.000001 else ec[i] for i in xrange(len(self.Houses)) ] # get gdf_proj gdf_proj = ox.project_gdf(self.gdf) # initial figure ground fig, ax = ox.plot_figure_ground(address=self.address, dist=self.radius, network_type=network_type, default_width=default_width, bgcolor='#333333', edge_color='w', street_widths=street_widths, save=False, show=False, close=True, fig_length=size) # plot the building fig, ax = ox.plot_buildings(gdf_proj, fig=fig, ax=ax, color=ec_after, set_bounds=True, save=True, show=False, close=True, filename=name, dpi=dpi) # save image Image('{}/{}.{}'.format(img_folder, name, extension), height=image_size, width=image_size) return fig, ax
G_bike = ox.load_graphml('{}_bike.graphml'.format(name), folder=path) if len(G_bike.nodes) > 0: G_bike = ox.project_graph(G_bike, to_crs={'init': 'epsg:4326'}) print(' + Bike loaded.') G_walk = ox.load_graphml('{}_walk.graphml'.format(name), folder=path) if len(G_walk.nodes) > 0: G_walk = ox.project_graph(G_walk, to_crs={'init': 'epsg:4326'}) print(' + Walk loaded') G_rail = ox.load_graphml('{}_rail.graphml'.format(name), folder=path) if len(G_rail.nodes) > 0: G_rail = ox.project_graph(G_rail, to_crs={'init': 'epsg:4326'}) print(' + Rail loaded') # 3.- Load the area gdf = gpd.read_file('../Data/{}/{}_shape/'.format(name, name)) gdf = ox.project_gdf(gdf, to_crs={'init': 'epsg:4326'}) print(' + Geometry loaded') layers = [G_walk, G_bike, G_rail, G_drive] widths = [1, 2, 1.5, 1] #4.- Plot print('\nStarting the ploting...') for layer, color, name_layer, width in zip(layers, colors_layers, names, widths): if len(layer.nodes) > 0: fig, ax = ox.plot_graph(layer, fig_height=30, show=False, close=False, edge_color=color, node_color=color,
def proportional_population_downscaling(df_osm_built, df_insee): """ Performs a proportional population downscaling considering the surface dedicated to residential land use Associates the estimated population to each building in column 'population' Parameters ---------- df_osm_built : geopandas.GeoDataFrame input buildings with computed residential surface df_insee : geopandas.GeoDataFrame INSEE population data Returns ---------- """ if (df_insee.crs != df_osm_built.crs): # If projections do not match # First project to Lat-Long coordinates, then project to UTM coordinates df_insee = ox.project_gdf(ox.project_gdf(df_insee, to_latlong=True)) # OSM Building geometries are already projected assert (df_insee.crs == df_osm_built.crs) df_osm_built['geom'] = df_osm_built.geometry df_osm_built_residential = df_osm_built[df_osm_built.apply( lambda x: x.landuses_m2['residential'] > 0, axis=1)] # Loading/saving using geopandas loses the 'ellps' key df_insee.crs = df_osm_built_residential.crs # Intersecting gridded population - buildings sjoin = gpd.sjoin(df_insee, df_osm_built_residential, op='intersects') # Calculate area within square (percentage of building with the square) sjoin['residential_m2_within'] = sjoin.apply( lambda x: x.landuses_m2['residential'] * (x.geom.intersection(x.geometry).area / x.geom.area), axis=1) # Initialize df_insee['residential_m2_within'] = 0 # Sum residential area within square sum_m2_per_square = sjoin.groupby( sjoin.index)['residential_m2_within'].sum() # Assign total residential area within each square df_insee.loc[sum_m2_per_square.index, "residential_m2_within"] = sum_m2_per_square.values # Get number of M^2 / person df_insee["m2_per_person"] = df_insee.apply( lambda x: x.residential_m2_within / x.pop_count, axis=1) def population_building(x, df_insee): # Sum of: For each square: M2 of building within square / M2 per person return (x.get('m2', []) / df_insee.loc[x.get('idx', [])].m2_per_person).sum() # Index: Buildings , Values: idx:Indices of gridded square population, m2: M2 within that square buildings_square_m2_association = sjoin.groupby('index_right').apply( lambda x: { 'idx': list(x.index), 'm2': list(x.residential_m2_within) }) # Associate df_osm_built.loc[buildings_square_m2_association.index, "population"] = buildings_square_m2_association.apply( lambda x: population_building(x, df_insee)) # Drop unnecessary column df_osm_built.drop('geom', axis=1, inplace=True)
def get_processed_osm_data( city_ref_file=None, region_args={ "polygon": None, "place": None, "which_result": 1, "point": None, "address": None, "distance": None, "north": None, "south": None, "east": None, "west": None }, kwargs={ "retrieve_graph": True, "default_height": 3, "meters_per_level": 3, "associate_landuses_m2": True, "mixed_building_first_floor_activity": True, "minimum_m2_building_area": 9, "date": None }): """ Retrieves buildings, building parts, and Points of Interest associated with a residential/activity land use from OpenStreetMap data for input city If a name for input city is given, the data will be loaded (if it was previously stored) If no stored files exist, it will query and process the data and store it under the city name Queries data for input region (polygon, place, point/address and distance around, or bounding box coordinates) Additional arguments will drive the overall process Parameters ---------- city_ref_file : str Name of input city / region region_args : dict contains the information to retrieve the region of interest as the following: polygon : shapely Polygon or MultiPolygon geographic shape to fetch the landuse footprints within place : string or dict query string or structured query dict to geocode/download which_result : int result number to retrieve from geocode/download when using query string point : tuple the (lat, lon) central point around which to construct the graph address : string the address to geocode and use as the central point around which to construct the graph distance : int retain only those nodes within this many meters of the center of the graph north : float northern latitude of bounding box south : float southern latitude of bounding box east : float eastern longitude of bounding box west : float western longitude of bounding box kwargs : dict additional arguments to drive the process: retrieve_graph : boolean that determines if the street network for input city has to be retrieved and stored default_height : float height of buildings under missing data meters_per_level : float buildings number of levels assumed under missing data associate_landuses_m2 : boolean compute the total square meter for each land use mixed_building_first_floor_activity : Boolean if True: Associates building's first floor to activity uses and the rest to residential uses if False: Associates half of the building's area to each land use (Activity and Residential) minimum_m2_building_area : float minimum area to be considered a building (otherwise filtered) date : datetime.datetime query the database at a certain timestamp Returns ---------- [ gpd.GeoDataFrame, gpd.GeoDataFrame, gpd.GeoDataFrame ] returns the output geo dataframe containing all buildings, building parts, and points associated to a residential or activity land usage """ log("OSM data requested for city: " + str(city_ref_file)) if (city_ref_file): geo_poly_file, geo_poly_parts_file, geo_point_file = get_dataframes_filenames( city_ref_file) ########################## ### Stored file ? ########################## if ((city_ref_file) and (os.path.isfile(geo_poly_file))): # File exists log("Found stored files for city " + city_ref_file) # Load local GeoDataFrames return load_geodataframe(geo_poly_file), load_geodataframe( geo_poly_parts_file), load_geodataframe(geo_point_file) # Get keyword arguments for input region of interest polygon, place, which_result, point, address, distance, north, south, east, west = region_args.get( "polygon"), region_args.get("place"), region_args.get( "which_result"), region_args.get("point"), region_args.get( "address"), region_args.get("distance"), region_args.get( "north"), region_args.get("south"), region_args.get( "east"), region_args.get("west") ### Valid input? if not (any([ not (polygon is None), place, point, address, north, south, east, west ])): log("Error: Must provide at least one type of input") return None, None, None if (kwargs.get("date")): # Non-null date date_ = kwargs.get("date").strftime("%Y-%m-%dT%H:%M:%SZ") log("Requesting OSM database at timestamp: " + date_) # e.g.: [date:"2004-05-06T00:00:00Z"] date_query = '[date:"' + date_ + '"]' else: date_query = "" ########################## ### Overpass query: Buildings ########################## # Query and update bounding box / polygon df_osm_built, polygon, north, south, east, west = create_buildings_gdf_from_input( date=date_query, polygon=polygon, place=place, which_result=which_result, point=point, address=address, distance=distance, north=north, south=south, east=east, west=west) df_osm_built["osm_id"] = df_osm_built.index df_osm_built.reset_index(drop=True, inplace=True) ########################## ### Overpass query: Land use polygons. Aid to perform buildings land use inference ########################## df_osm_lu = create_landuse_gdf(date=date_query, polygon=polygon, north=north, south=south, east=east, west=west) df_osm_lu["osm_id"] = df_osm_lu.index # Drop useless columns columns_of_interest = ["osm_id", "geometry", "landuse"] df_osm_lu.drop([ col for col in list(df_osm_lu.columns) if not col in columns_of_interest ], axis=1, inplace=True) df_osm_lu.reset_index(drop=True, inplace=True) ########################## ### Overpass query: POIs ########################## df_osm_pois = create_pois_gdf(date=date_query, polygon=polygon, north=north, south=south, east=east, west=west) df_osm_pois["osm_id"] = df_osm_pois.index df_osm_pois.reset_index(drop=True, inplace=True) ########## ### Overpass query: Building parts. Allow to calculate the real amount of M^2 for each building ########## df_osm_building_parts = create_building_parts_gdf(date=date_query, polygon=polygon, north=north, south=south, east=east, west=west) # Filter rows not needed (roof, etc) and not building already exists in buildings extract if ("building" in df_osm_building_parts.columns): df_osm_building_parts = df_osm_building_parts[ (~df_osm_building_parts["building:part"].isin( building_parts_to_filter)) & (~df_osm_building_parts["building:part"].isnull()) & (df_osm_building_parts["building"].isnull())] else: df_osm_building_parts = df_osm_building_parts[ (~df_osm_building_parts["building:part"].isin( building_parts_to_filter)) & (~df_osm_building_parts["building:part"].isnull())] df_osm_building_parts["osm_id"] = df_osm_building_parts.index df_osm_building_parts.reset_index(drop=True, inplace=True) log("Done: OSM data request") #################################################### ### Sanity check of height tags #################################################### sanity_check_height_tags(df_osm_built) sanity_check_height_tags(df_osm_building_parts) def remove_nan_dict(x): # Remove entries with nan values return {k: v for k, v in x.items() if pd.notnull(v)} df_osm_built['height_tags'] = df_osm_built[[ c for c in height_tags if c in df_osm_built.columns ]].apply(lambda x: remove_nan_dict(x.to_dict()), axis=1) df_osm_building_parts['height_tags'] = df_osm_building_parts[[ c for c in height_tags if c in df_osm_building_parts.columns ]].apply(lambda x: remove_nan_dict(x.to_dict()), axis=1) ########### ### Remove columns which do not provide valuable information ########### columns_of_interest = columns_osm_tag + [ "osm_id", "geometry", "height_tags" ] df_osm_built.drop([ col for col in list(df_osm_built.columns) if not col in columns_of_interest ], axis=1, inplace=True) df_osm_building_parts.drop([ col for col in list(df_osm_building_parts.columns) if not col in columns_of_interest ], axis=1, inplace=True) columns_of_interest = columns_osm_tag + ["osm_id", "geometry"] df_osm_pois.drop([ col for col in list(df_osm_pois.columns) if not col in columns_of_interest ], axis=1, inplace=True) log('Done: Sanity check + drop unnecesary columns') ########### ### Classification ########### df_osm_built['classification'], df_osm_built['key_value'] = list( zip(*df_osm_built.apply(classify_tag, axis=1))) df_osm_pois['classification'], df_osm_pois['key_value'] = list( zip(*df_osm_pois.apply(classify_tag, axis=1))) df_osm_building_parts['classification'], df_osm_building_parts[ 'key_value'] = list( zip(*df_osm_building_parts.apply(classify_tag, axis=1))) # Remove unnecesary buildings df_osm_built.drop(df_osm_built[df_osm_built.classification.isnull()].index, inplace=True) df_osm_built.reset_index(inplace=True, drop=True) # Remove unnecesary POIs df_osm_pois.drop( df_osm_pois[df_osm_pois.classification.isin(["infer", "other"]) | df_osm_pois.classification.isnull()].index, inplace=True) df_osm_pois.reset_index(inplace=True, drop=True) # Building parts will acquire its containing building land use if it is not available df_osm_building_parts.loc[ df_osm_building_parts.classification.isin(["infer", "other"]), "classification"] = None log('Done: OSM tags classification') ########### ### Remove already used tags ########### df_osm_built.drop( [c for c in columns_osm_tag if c in df_osm_built.columns], axis=1, inplace=True) df_osm_pois.drop([c for c in columns_osm_tag if c in df_osm_pois.columns], axis=1, inplace=True) df_osm_building_parts.drop( [c for c in columns_osm_tag if c in df_osm_building_parts.columns], axis=1, inplace=True) ########### ### Project, drop small buildings and reset indices ########### ### Project to UTM coordinates within the same zone df_osm_built = ox.project_gdf(df_osm_built) df_osm_lu = ox.project_gdf(df_osm_lu, to_crs=df_osm_built.crs) df_osm_pois = ox.project_gdf(df_osm_pois, to_crs=df_osm_built.crs) df_osm_building_parts = ox.project_gdf(df_osm_building_parts, to_crs=df_osm_built.crs) # Drop buildings with an area lower than a threshold df_osm_built.drop(df_osm_built[ df_osm_built.geometry.area < kwargs["minimum_m2_building_area"]].index, inplace=True) log('Done: Geometries reprojection') #################################################### ### Infer buildings land use (under uncertainty) #################################################### compute_landuse_inference(df_osm_built, df_osm_lu) # Free space del df_osm_lu assert (len(df_osm_built[df_osm_built.key_value == { "inferred": "other" }]) == 0) assert (len(df_osm_built[df_osm_built.classification.isnull()]) == 0) assert (len(df_osm_pois[df_osm_pois.classification.isnull()]) == 0) log('Done: Land use deduction') #################################################### ### Associate for each building, its containing building parts and Points of interest #################################################### associate_structures(df_osm_built, df_osm_building_parts, operation='contains', column='containing_parts') associate_structures(df_osm_built, df_osm_pois, operation='intersects', column='containing_poi') # Classify activity types df_osm_built['activity_category'] = df_osm_built.apply( lambda x: classify_activity_category(x.key_value), axis=1) df_osm_pois['activity_category'] = df_osm_pois.apply( lambda x: classify_activity_category(x.key_value), axis=1) df_osm_building_parts['activity_category'] = df_osm_building_parts.apply( lambda x: classify_activity_category(x.key_value), axis=1) log('Done: Building parts association + activity categorization') #################################################### ### Associate effective number of levels, and measure the surface dedicated to each land use per building #################################################### if (kwargs["associate_landuses_m2"]): default_height = kwargs["default_height"] meters_per_level = kwargs["meters_per_level"] mixed_building_first_floor_activity = kwargs[ "mixed_building_first_floor_activity"] compute_landuses_m2(df_osm_built, df_osm_building_parts, df_osm_pois, default_height=default_height, meters_per_level=meters_per_level, mixed_building_first_floor_activity= mixed_building_first_floor_activity) df_osm_built.loc[ df_osm_built.activity_category.apply(lambda x: len(x) == 0), "activity_category"] = np.nan df_osm_pois.loc[df_osm_pois.activity_category.apply(lambda x: len(x) == 0), "activity_category"] = np.nan df_osm_building_parts.loc[ df_osm_building_parts.activity_category.apply(lambda x: len(x) == 0), "activity_category"] = np.nan if (kwargs["associate_landuses_m2"]): # Set the composed classification given, for each building, its containing Points of Interest and building parts classification df_osm_built.loc[df_osm_built.apply(lambda x: x.landuses_m2[ "activity"] > 0 and x.landuses_m2["residential"] > 0, axis=1), "classification"] = "mixed" log('Done: Land uses surface association') ########################## ### Overpass query: Street network graph ########################## if (kwargs["retrieve_graph"]): # Save graph for input city shape get_route_graph(city_ref_file, date=date_query, polygon=polygon, north=north, south=south, east=east, west=west, force_crs=df_osm_built.crs) log('Done: Street network graph retrieval') ########################## ### Store file ? ########################## if (city_ref_file): # File exists # Save GeoDataFrames store_geodataframe(df_osm_built, geo_poly_file) store_geodataframe(df_osm_building_parts, geo_poly_parts_file) store_geodataframe(df_osm_pois, geo_point_file) log("Storing file for city: " + city_ref_file) return df_osm_built, df_osm_building_parts, df_osm_pois
bars = ax.bar( division * np.pi/180 - width * 0.5, count/np.max(count), width=width, bottom=0., ec='k', lw=1, fc=sty.NC ) if EXPORT: fig.savefig( '{}/img/{}-{}-D.{}'.format(PTH_BASE, idStr, netType, FMT), bbox_inches='tight', pad_inches=.01 ) ############################################################################### # Plot the original network ############################################################################### G = ox.project_graph(G) gdf = ox.gdf_from_place(PLACE) area = ox.project_gdf(gdf).unary_union.area if EXPORT: file = open('{}/dta/{}-{}-G.pickle'.format(PTH_BASE, idStr, netType), 'wb') pkl.dump(G, file) file.close() (fig, ax) = ox.plot_graph( G, show=False, bgcolor=sty.BKG, node_size=sty.NS*5, node_color=sty.NC, node_zorder=sty.NZ, node_alpha=.35, edge_linewidth=sty.ES, edge_color=sty.EC, edge_alpha=sty.EA ) if EXPORT: fig.savefig( '{}/img/{}-{}-O.{}'.format(PTH_BASE, idStr, netType, FMT), bbox_inches='tight', pad_inches=.01