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)
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
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
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')
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
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())
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
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)
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
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
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)
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)
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')
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