Esempio n. 1
0
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)
Esempio n. 2
0
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)
        


Esempio n. 4
0
        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)
Esempio n. 5
0
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")
Esempio n. 6
0
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)
Esempio n. 8
0
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])
Esempio n. 9
0
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)
Esempio n. 10
0
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,
Esempio n. 11
0
################################################################################
# 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)
Esempio n. 12
0
    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
Esempio n. 13
0
    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,
Esempio n. 14
0
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)
Esempio n. 15
0
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
Esempio n. 16
0
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