コード例 #1
0
def geometry_extractor_osm(locator, config):
    """this is where the action happens if it is more than a few lines in ``main``.
    NOTE: ADD YOUR SCRIPT'S DOCUMENATION HERE (how)
    NOTE: RENAME THIS FUNCTION (SHOULD PROBABLY BE THE SAME NAME AS THE MODULE)
    """

    # local variables:
    buffer_m = config.surroundings_helper.buffer
    buildings_height = config.surroundings_helper.height_ag
    buildings_floors = config.surroundings_helper.floors_ag
    shapefile_out_path = locator.get_surroundings_geometry()
    zone = gdf.from_file(locator.get_zone_geometry())

    # trnasform zone file to geographic coordinates
    zone = zone.to_crs(get_geographic_coordinate_system())
    lon = zone.geometry[0].centroid.coords.xy[0][0]
    lat = zone.geometry[0].centroid.coords.xy[1][0]
    zone = zone.to_crs(get_projected_coordinate_system(float(lat), float(lon)))

    # get a polygon of the surrounding area, and one polygon representative of the zone area
    print("Calculating surrounding area")
    area_with_buffer = calc_surrounding_area(zone, buffer_m)

    # get footprints of all the surroundings
    print("Getting building footprints")
    area_with_buffer_polygon = area_with_buffer.to_crs(
        get_geographic_coordinate_system()).geometry.values[0]
    all_surroundings = osmnx.footprints.footprints_from_polygon(
        polygon=area_with_buffer_polygon)
    all_surroundings = all_surroundings.to_crs(
        get_projected_coordinate_system(float(lat), float(lon)))

    # erase overlapping area
    print("Removing unwanted buildings")
    surroundings = erase_no_surrounding_areas(all_surroundings, zone,
                                              area_with_buffer)

    assert surroundings.shape[
        0] > 0, 'No buildings were found within range based on buffer parameter.'

    # clean attributes of height, name and number of floors
    result = clean_attributes(surroundings,
                              buildings_height,
                              buildings_floors,
                              key="CEA")
    result = result.to_crs(
        get_projected_coordinate_system(float(lat), float(lon)))

    # save to shapefile
    result.to_file(shapefile_out_path)
コード例 #2
0
def calc_bounding_box_projected_coordinates(shapefile_zone, shapefile_surroundings):

    # connect both files and avoid repetition
    data_zone = Gdf.from_file(shapefile_zone)
    data_dis = Gdf.from_file(shapefile_surroundings)
    data_dis = data_dis.loc[~data_dis["Name"].isin(data_zone["Name"])]
    data = data_dis.append(data_zone, ignore_index = True, sort=True)
    data = data.to_crs(get_geographic_coordinate_system())
    lon = data.geometry[0].centroid.coords.xy[0][0]
    lat = data.geometry[0].centroid.coords.xy[1][0]
    crs = get_projected_coordinate_system(float(lat), float(lon))
    data = data.to_crs(get_projected_coordinate_system(float(lat), float(lon)))
    result = data.total_bounds
    result = [np.float32(x) for x in result]  # in float32 so the raster works
    return result, crs, lon, lat
コード例 #3
0
def polygon_to_zone(buildings_floors, buildings_floors_below_ground,
                    buildings_height, buildings_height_below_ground, poly,
                    shapefile_out_path):
    poly = poly.to_crs(get_geographic_coordinate_system())
    lon = poly.geometry[0].centroid.coords.xy[0][0]
    lat = poly.geometry[0].centroid.coords.xy[1][0]
    # get footprints of all the district
    poly = osmnx.footprints.footprints_from_polygon(
        polygon=poly['geometry'].values[0])

    # clean geometries
    poly = clean_geometries(poly)

    # clean attributes of height, name and number of floors
    result, result_allfields = clean_attributes(poly,
                                                buildings_height,
                                                buildings_floors,
                                                buildings_height_below_ground,
                                                buildings_floors_below_ground,
                                                key="B")
    result = result.to_crs(
        get_projected_coordinate_system(float(lat), float(lon)))

    # save to shapefile
    result.to_file(shapefile_out_path)

    return result_allfields
コード例 #4
0
def write_coordinates_to_shp_file(config, locator, list_geotranch, name):
    """
    Write grid.shp and thermal_network.shp on base of list of coordinate data

    :param list_geotranch: tuples with geo data of startnode and endnode
    :type list_geotranch: list(float, float)
    :param name: filename of shp file
    :type name: string
    :return: shp file stored in \\inputs\\networks\\
    :rtype: Nonetype

    """

    input_street_shp = locator.get_street_network()
    output_path_shp = locator.get_electric_network_output_location(name)

    geometry = [
        shapely.geometry.LineString(json.loads(g)) for g in list_geotranch
    ]

    gdf_street = gpd.GeoDataFrame.from_file(input_street_shp)
    lat, lon = get_lat_lon_projected_shapefile(gdf_street)
    crs = get_projected_coordinate_system(lat, lon)
    gdf = gpd.GeoDataFrame(crs=crs, geometry=geometry)

    gdf.to_file(output_path_shp,
                driver='ESRI Shapefile',
                encoding='ISO-8859-1')
コード例 #5
0
def calc_building_centroids(input_buildings_shp,
                            temp_path_building_centroids_shp,
                            list_district_scale_buildings,
                            plant_buildings,
                            consider_only_buildings_with_demand=False,
                            type_network="DH",
                            total_demand=False):
    # # get coordinate system and project to WSG 84
    zone_df = gdf.from_file(input_buildings_shp)
    zone_df = zone_df.loc[zone_df['Name'].isin(list_district_scale_buildings +
                                               plant_buildings)]
    zone_df = zone_df.reset_index(drop=True)

    # get only buildings with a demand, send out a message if there are less than 2 buildings.
    if consider_only_buildings_with_demand:
        total_demand = pd.read_csv(total_demand)
        if type_network == "DH":
            field = "QH_sys_MWhyr"
        elif type_network == "DC":
            field = "QC_sys_MWhyr"
        buildings_with_load = total_demand[
            total_demand[field] > 0.0].Name.tolist()
        selected_buildings = list(
            set(buildings_with_load).union(set(plant_buildings)))
        if len(selected_buildings) >= 2:
            zone_df = zone_df.loc[zone_df['Name'].isin(selected_buildings)]
            zone_df = zone_df.reset_index(drop=True)
        else:
            raise Exception(
                "We could not find two or more buildings with thermal energy demand the network layout "
                "will not work unless the consider_only_buildings_with_demand parameter is set to False"
            )

    zone_df = zone_df.to_crs(get_geographic_coordinate_system())
    lon = zone_df.geometry[0].centroid.coords.xy[0][0]
    lat = zone_df.geometry[0].centroid.coords.xy[1][0]

    # get coordinate system and re project to UTM
    zone_df = zone_df.to_crs(get_projected_coordinate_system(lat, lon))

    # create points with centroid
    points = zone_df.copy()
    points.geometry = zone_df['geometry'].centroid

    # # decrease the number of units of the points
    building_centroids_df = simplify_points_accurracy(points,
                                                      SHAPEFILE_TOLERANCE,
                                                      points.crs)

    # saving result
    building_centroids_df.to_file(temp_path_building_centroids_shp,
                                  driver='ESRI Shapefile')

    return building_centroids_df
コード例 #6
0
ファイル: routes.py プロジェクト: nasty-bos/CityEnergyAnalyst
def route_get_building_properties():
    import cea.glossary

    div = request.args.get('div', default=False)

    # FIXME: Find a better way to ensure order of tabs
    tabs = ['zone', 'age', 'occupancy', 'architecture', 'internal-loads', 'indoor-comfort', 'air-conditioning-systems',
            'supply-systems', 'emission-intensity', 'surroundings']

    locator = cea.inputlocator.InputLocator(current_app.cea_config.scenario)
    store = {'tables': {}, 'geojsons': {}, 'columns': {}, 'column_types': {}, 'crs': {}, 'glossary': {}}
    glossary = cea.glossary.read_glossary_df()
    for db in INPUTS:
        db_info = INPUTS[db]
        location = getattr(locator, db_info['location'])()
        try:
            if db_info['type'] == 'shp':

                from cea.utilities.standardize_coordinates import shapefile_to_WSG_and_UTM, \
                    get_geographic_coordinate_system
                table_df, lat, lon = shapefile_to_WSG_and_UTM(location)

                # save projected coordinate system
                store['crs'][db] = get_projected_coordinate_system(lat, lon)

                store['geojsons'][db] = json.loads(
                    table_df.to_crs(get_geographic_coordinate_system()).to_json(show_bbox=True))

                table_df = pandas.DataFrame(table_df.drop(columns='geometry'))
                if 'REFERENCE' in db_info['fieldnames'] and 'REFERENCE' not in table_df.columns:
                    table_df['REFERENCE'] = None
                store['tables'][db] = json.loads(table_df.set_index('Name').to_json(orient='index'))
            else:
                assert db_info['type'] == 'dbf', 'Unexpected database type: %s' % db_info['type']
                table_df = cea.utilities.dbf.dbf_to_dataframe(location)
                if 'REFERENCE' in db_info['fieldnames'] and 'REFERENCE' not in table_df.columns:
                    table_df['REFERENCE'] = None
                store['tables'][db] = json.loads(table_df.set_index('Name').to_json(orient='index'))

            store['columns'][db] = db_info['fieldnames']
            store['column_types'][db] = {k: v.__name__ for k, v in db_info['fieldtypes'].items()}

            filenames = glossary['FILE_NAME'].str.split(pat='/').str[-1]
            store['glossary'].update(json.loads(glossary[filenames == '%s.%s' % (db.replace('-', '_'), db_info['type'])]
                                                [['VARIABLE', 'UNIT', 'DESCRIPTION']].set_index('VARIABLE').to_json(
                orient='index')))

        except IOError as e:
            print(e)
            store['tables'][db] = {}
    return render_template('table.html' if not div else 'input_editor_electron.html',
                           store=store, tabs=tabs, last_updated=dir_last_updated())
コード例 #7
0
def calc_connectivity_network(path_streets_shp, building_centroids_df, temp_path_potential_network_shp):
    """
    This script outputs a potential network connecting a series of building points to the closest street network
    the street network is assumed to be a good path to the district heating or cooling network

    :param path_streets_shp: path to street shapefile
    :param building_centroids_df: path to substations in buildings (or close by)
    :param path_potential_network: output path shapefile
    :return:
    """
    # first get the street network
    street_network = gdf.from_file(path_streets_shp)

    # check coordinate system
    street_network = street_network.to_crs(get_geographic_coordinate_system())
    lon = street_network.geometry[0].centroid.coords.xy[0][0]
    lat = street_network.geometry[0].centroid.coords.xy[1][0]
    street_network = street_network.to_crs(get_projected_coordinate_system(lat, lon))
    crs = street_network.crs

    street_network = simplify_liness_accurracy(street_network.geometry.values, SHAPEFILE_TOLERANCE, crs)

    # create terminals/branches form street to buildings
    prototype_network = create_terminals(building_centroids_df, crs, street_network)
    config = cea.config.Configuration()
    locator = cea.inputlocator.InputLocator(scenario=config.scenario)

    # first split in intersections
    prototype_network = one_linestring_per_intersection(prototype_network.geometry.values,
                                                        crs)
    # snap endings of all vectors to ending of all other vectors
    prototype_network = snappy_endings(prototype_network.geometry.values, SNAP_TOLERANCE, crs)

    # calculate intersections
    gdf_points_snapped = calculate_end_points_intersections(prototype_network, crs)

    # snap these points to the lines and transform lines
    gdf_points_snapped, prototype_network = snap_points(gdf_points_snapped, prototype_network, SNAP_TOLERANCE, crs)

    # save for verification purposes
    prototype_network.to_file(locator.get_temporary_file("prototype_network.shp"), driver='ESRI Shapefile')
    # get segments
    potential_network_df = split_line_by_nearest_points(prototype_network, gdf_points_snapped, 1.0, crs)

    # calculate Shape_len field
    potential_network_df["Shape_Leng"] = potential_network_df["geometry"].apply(lambda x: x.length)

    potential_network_df.to_file(temp_path_potential_network_shp, driver='ESRI Shapefile')

    return crs
コード例 #8
0
def geometry_extractor_osm(locator, config):
    """this is where the action happens if it is more than a few lines in ``main``.
    NOTE: ADD YOUR SCRIPT'S DOCUMENATION HERE (how)
    NOTE: RENAME THIS FUNCTION (SHOULD PROBABLY BE THE SAME NAME AS THE MODULE)
    """

    # local variables:
    list_of_bounding_box = config.streets_helper.bbox
    type_of_streets = config.streets_helper.streets
    shapefile_out_path = locator.get_street_network()
    extra_border = 0.0010 # adding extra 150m (in degrees equivalent) to avoid errors of no data

    #get the bounding box coordinates
    if list_of_bounding_box == []:
        # the list is empty, we then revert to get the bounding box for the district
        assert os.path.exists(
            locator.get_surroundings_geometry()), 'Get surroundings geometry file first or the coordinates of the area where to extract the streets from in the next format: lon_min, lat_min, lon_max, lat_max: %s'
        print("generating streets from Surroundings Geometry")
        bounding_box_surroundings_file = calc_bounding_box(locator.get_surroundings_geometry(), locator.get_zone_geometry())
        lon_min = bounding_box_surroundings_file[0]-extra_border
        lat_min = bounding_box_surroundings_file[1]-extra_border
        lon_max = bounding_box_surroundings_file[2]+extra_border
        lat_max = bounding_box_surroundings_file[3]+extra_border
    elif len(list_of_bounding_box) == 4:
        print("generating streets from your bounding box")
        # the list is not empty, the user has indicated a specific set of coordinates
        lon_min = list_of_bounding_box[0]-extra_border
        lat_min = list_of_bounding_box[1]-extra_border
        lon_max = list_of_bounding_box[2]+extra_border
        lat_max = list_of_bounding_box[3]+extra_border
    elif len(list_of_bounding_box) != 4:
        raise ValueError(
            "Please indicate the coordinates of the area where to extract the streets from in the next format: lon_min, lat_min, lon_max, lat_max")

    #get and clean the streets
    G = ox.graph_from_bbox(north=lat_max, south=lat_min, east=lon_max, west=lon_min,
                           network_type=type_of_streets)
    data = ox.save_load.graph_to_gdfs(G, nodes=False, edges=True, node_geometry=False, fill_edge_geometry=True)

    #project coordinate system
    data = data.to_crs(get_projected_coordinate_system(float(lat_min), float(lon_min)))

    #clean data and save to shapefile
    data.loc[:, "highway"] = [x[0] if type(x) == list else x for x in data["highway"].values]
    data.loc[:, "name"] = [x[0] if type(x) == list else x for x in data["name"].values]
    data.fillna(value="Unknown", inplace=True)
    data[['geometry', "name", "highway"]].to_file(shapefile_out_path)
コード例 #9
0
def calc_substation_location(input_buildings_shp,
                             output_substations_shp,
                             connected_buildings,
                             consider_only_buildings_with_demand=False,
                             type_network="DH",
                             total_demand=False):
    # # get coordinate system and project to WSG 84
    poly = gdf.from_file(input_buildings_shp)
    if connected_buildings != []:
        # get only buildings described
        poly = poly.loc[poly['Name'].isin(connected_buildings)]
        poly = poly.reset_index(drop=True)

    # get only buildings with a demand, send out a message if there are less than 2 buildings.
    if consider_only_buildings_with_demand:
        total_demand = pd.read_csv(total_demand)
        if type_network == "DH":
            field = "QH_sys_MWhyr"
        elif type_network == "DC":
            field = "QC_sys_MWhyr"
        buildings_with_load_df = total_demand[total_demand[field] > 0.0]
        if buildings_with_load_df.shape[0] >= 2:
            buildings_with_load = buildings_with_load_df['Name'].tolist()
            poly = poly.loc[poly['Name'].isin(buildings_with_load)]
            poly = poly.reset_index(drop=True)
        else:
            raise Exception(
                "We could not find two or more buildings with thermal energy demand the network layout "
                "will not work unless the consider_only_buildings_with_demand parameter is set to False"
            )

    poly = poly.to_crs(get_geographic_coordinate_system())
    lon = poly.geometry[0].centroid.coords.xy[0][0]
    lat = poly.geometry[0].centroid.coords.xy[1][0]

    # get coordinate system and re project to UTM
    poly = poly.to_crs(get_projected_coordinate_system(lat, lon))

    # create points
    points = poly.copy()
    points.geometry = poly['geometry'].centroid

    # saving result
    points.to_file(output_substations_shp, driver='ESRI Shapefile')

    return points, poly
コード例 #10
0
def df_to_json(file_location, bbox=False):
    from cea.utilities.standardize_coordinates import get_lat_lon_projected_shapefile, get_projected_coordinate_system

    try:
        table_df = geopandas.GeoDataFrame.from_file(file_location)
        # Save coordinate system
        lat, lon = get_lat_lon_projected_shapefile(table_df)
        crs = get_projected_coordinate_system(lat, lon)
        # make sure that the geojson is coded in latitude / longitude
        out = table_df.to_crs(get_geographic_coordinate_system())
        out = json.loads(out.to_json(show_bbox=bbox))
        return out, crs
    except (IOError, DriverError) as e:
        print(e)
        return None, None
    except Exception as e:
        traceback.print_exc()
        return None, None
コード例 #11
0
    def write(self, df, *args, **kwargs):
        """
        :type df: geopandas.GeoDataFrame
        """
        from cea.utilities.standardize_coordinates import (
            get_lat_lon_projected_shapefile, get_projected_coordinate_system)
        self.validate(df)
        path_to_shp = self(*args, **kwargs)

        parent_folder = os.path.dirname(path_to_shp)
        if not os.path.exists(parent_folder):
            os.makedirs(parent_folder)
        lat, lon = get_lat_lon_projected_shapefile(df)

        # get coordinate system and re project to UTM
        df = df.to_crs(get_projected_coordinate_system(lat, lon))

        df.to_file(path_to_shp)
コード例 #12
0
def df_to_json(file_location, bbox=False, trigger_abort=True):
    from cea.utilities.standardize_coordinates import get_lat_lon_projected_shapefile, get_projected_coordinate_system
    try:
        table_df = geopandas.GeoDataFrame.from_file(file_location)
        # Save coordinate system
        lat, lon = get_lat_lon_projected_shapefile(table_df)
        crs = get_projected_coordinate_system(lat, lon)
        # make sure that the geojson is coded in latitude / longitude
        out = table_df.to_crs(get_geographic_coordinate_system())
        out = json.loads(out.to_json(show_bbox=bbox))
        return out, crs
    except IOError as e:
        print(e)
        if trigger_abort:
            abort(400, 'Input file not found: %s' % file_location)
    except RuntimeError as e:
        print(e)
        if trigger_abort:
            abort(400, e.message)
コード例 #13
0
def calc_substation_location(input_buildings_shp, output_substations_shp, connected_buildings):

    # # get coordinate system and project to WSG 84
    poly = gdf.from_file(input_buildings_shp)
    if connected_buildings != []:
        #get only buildings
        poly = poly.loc[poly['Name'].isin(connected_buildings)]
        poly = poly.reset_index(drop=True)

    poly = poly.to_crs(get_geographic_coordinate_system())
    lon = poly.geometry[0].centroid.coords.xy[0][0]
    lat = poly.geometry[0].centroid.coords.xy[1][0]

    # get coordinate system and re project to UTM
    poly = poly.to_crs(get_projected_coordinate_system(lat, lon))

    # create points
    points = poly.copy()
    points.geometry = poly['geometry'].centroid

    # saving result
    points.to_file(output_substations_shp, driver='ESRI Shapefile')
コード例 #14
0
def calc_connectivity_network(path_streets_shp, path_connection_point_buildings_shp, path_potential_network):
    """
    This script outputs a potential network connecting a series of building points to the closest street network
    the street network is assumed to be a good path to the district heating or cooling network

    :param path_streets_shp: path to street shapefile
    :param path_connection_point_buildings_shp: path to substations in buildings (or close by)
    :param path_potential_network: output path shapefile
    :return:
    """
    # first get the building centroids and the street network
    buiding_centroids = gdf.from_file(path_connection_point_buildings_shp)
    street_network = gdf.from_file(path_streets_shp)

    # check coordinate system
    street_network = street_network.to_crs(get_geographic_coordinate_system())
    lon = street_network.geometry[0].centroid.coords.xy[0][0]
    lat = street_network.geometry[0].centroid.coords.xy[1][0]
    street_network = street_network.to_crs(get_projected_coordinate_system(lat, lon))
    crs = street_network.crs

    # # decrease the number of units of the points
    tolerance = 6
    buiding_centroids = simplify_points_accurracy(buiding_centroids, tolerance, crs)
    street_network = simplify_liness_accurracy(street_network.geometry.values, tolerance, crs)

    # create terminals/branches form street to buildings
    prototype_network = create_terminals(buiding_centroids, crs, street_network)
    config = cea.config.Configuration()
    locator=cea.inputlocator.InputLocator(scenario=config.scenario)
    prototype_network.to_file(locator.get_temporary_file("prototype_network.shp"), driver='ESRI Shapefile')


    # first split in intersections
    prototype_network = one_linestring_per_intersection(prototype_network.geometry.values,
                                                        crs)

    # snap endings of all vectors to ending of all other vectors
    prototype_network = snappy_endings(prototype_network.geometry.values, 0.5, crs)

    # calculate intersections
    gdf_points_snapped = calculate_end_points_intersections(prototype_network, crs)

    # snap these points to the lines and transform lines
    gdf_points_snapped, prototype_network = snap_points(gdf_points_snapped, prototype_network,
                                                        crs)
    # get segments
    gdf_segments = split_line_by_nearest_points(prototype_network, gdf_points_snapped, 1.0, crs)

    # calculate Shape_len field
    gdf_segments["Shape_Leng"] = gdf_segments["geometry"].apply(lambda x: x.length)

    # add length to segments
    # gdf_segments.plot()
    # import matplotlib.pyplot as plt
    # gdf_points.plot()
    # gdf_points_snapped.plot()
    # plt.show()
    # x=1
    gdf_segments.to_file(path_potential_network, driver='ESRI Shapefile')

    return crs