def test_geometry_length__linestring(): geod = Geod(ellps="WGS84") assert_almost_equal( geod.geometry_length(LineString([Point(1, 2), Point(3, 4)])), 313588.39721259556, decimal=2, )
def test_geometry_length__multilinestring(): geod = Geod(ellps="WGS84") line_string = LineString([Point(1, 2), Point(3, 4), Point(5, 2)]) assert_almost_equal( geod.geometry_length(MultiLineString([line_string, line_string])), 1254353.5888503822, decimal=2, )
def test_geometry_length__multipolygon(): geod = Geod(ellps="WGS84") polygon = Polygon(LineString([Point(1, 2), Point(3, 4), Point(5, 2)])) assert_almost_equal( geod.geometry_length(MultiPolygon([polygon, polygon])), 2 * 1072185.2103813463, decimal=2, )
def test_geometry_length__polygon(): geod = Geod(ellps="WGS84") assert_almost_equal( geod.geometry_length( Polygon(LineString([Point(1, 2), Point(3, 4), Point(5, 2)])) ), 1072185.2103813463, decimal=2, )
def test_geometry_length__linestring__radians(): geod = Geod(ellps="WGS84") assert_almost_equal( geod.geometry_length( LineString([ Point(math.radians(1), math.radians(2)), Point(math.radians(3), math.radians(4)), ]), radians=True, ), 313588.39721259556, decimal=2, )
def test_geometry_length__multipolygon__radians(): geod = Geod(ellps="WGS84") polygon = Polygon( LineString([ Point(math.radians(1), math.radians(2)), Point(math.radians(3), math.radians(4)), Point(math.radians(5), math.radians(2)), ])) assert_almost_equal( geod.geometry_length(MultiPolygon([polygon, polygon]), radians=True), 2 * 1072185.2103813463, decimal=2, )
def test_geometry_length__polygon__radians(): geod = Geod(ellps="WGS84") assert_almost_equal( geod.geometry_length( Polygon( LineString([ Point(math.radians(1), math.radians(2)), Point(math.radians(3), math.radians(4)), Point(math.radians(5), math.radians(2)), ])), radians=True, ), 1072185.2103813463, decimal=2, )
def to_graph(link_path, node_path): adjacency_list = defaultdict(list) with fiona.open(link_path) as link_collection,\ fiona.open(node_path) as node_collection: nodes_coordinates = [] nodes_ids = [] for rec in node_collection: nodes_coordinates.append(rec['geometry']['coordinates']) nodes_ids.append(rec['properties']['id']) kdtree = KDTree(nodes_coordinates) geod = Geod(ellps="WGS84") for rec in link_collection: direction = rec['properties']['dir'] vel_AB = rec['properties']['VEL_AB'] vel_BA = rec['properties']['VEL_BA'] length = geod.geometry_length(shape(rec['geometry'])) time_AB = length / vel_AB * (60/1000) * 60 time_BA = length / vel_BA * (60/1000) * 60 start_point = rec['geometry']['coordinates'][0] end_point = rec['geometry']['coordinates'][-1] start_distance, start_pos = kdtree.query(start_point) end_distance, end_pos = kdtree.query(end_point) start_id = nodes_ids[start_pos] end_id = nodes_ids[end_pos] if direction == 1: adjacency_list[start_id].append((time_AB, end_id)) elif direction == -1: adjacency_list[end_id].append((time_BA, start_id)) elif direction == 0: adjacency_list[start_id].append((time_AB, end_id)) adjacency_list[end_id].append((time_BA, start_id)) else: raise ValueError(direction) return adjacency_list
def get_reachMeasure(intersectionPoint, flowlines, *raindropPath): """Collect NHD Flowline Reach Code and Measure""" print('intersectionPoint: ', intersectionPoint) # Set Geoid to measure distances in meters geod = Geod(ellps="WGS84") # Convert the flowline to a geometry colelction to be exported nhdGeom = flowlines['features'][0]['geometry'] nhdFlowline = GeometryCollection([shape(nhdGeom)])[0] # Select the stream name from the NHD Flowline streamname = flowlines['features'][0]['properties']['gnis_name'] if streamname == ' ': streamname = 'none' # Create streamInfo dict and add some data streamInfo = { 'gnis_name': streamname, 'comid': flowlines['features'][0]['properties']['comid'], # 'lengthkm': flowlines['features'][0]['properties']['lengthkm'], 'intersectionPoint': (intersectionPoint.coords[0][1], intersectionPoint.coords[0][0]), 'reachcode': flowlines['features'][0]['properties']['reachcode'] } # Add more data to the streamInfo dict if raindropPath: streamInfo['raindropPathDist'] = round( geod.geometry_length(raindropPath[0]), 2) # If the intersectionPoint is on the NHD Flowline, split the flowline at the point if nhdFlowline.intersects(intersectionPoint) is True: NHDFlowlinesCut = split(nhdFlowline, intersectionPoint) # If they don't intersect (weird right?), buffer the intersectionPoint and then split the flowline if nhdFlowline.intersects(intersectionPoint) is False: buffDist = intersectionPoint.distance(nhdFlowline) * 1.01 buffIntersectionPoint = intersectionPoint.buffer(buffDist) NHDFlowlinesCut = split(nhdFlowline, buffIntersectionPoint) # print('NHDFlowlinesCut: ', len(NHDFlowlinesCut), NHDFlowlinesCut) # If the NHD Flowline was split, then calculate measure try: NHDFlowlinesCut[1] except: # If NHDFlowline was not split, then the intersectionPoint is either the first or last point on the NHDFlowline startPoint = Point(nhdFlowline[0].coords[0][0], nhdFlowline[0].coords[0][1]) lastPointID = len(nhdFlowline[0].coords) - 1 lastPoint = Point(nhdFlowline[0].coords[lastPointID][0], nhdFlowline[0].coords[lastPointID][1]) if (intersectionPoint == startPoint): streamInfo['measure'] = 100 if (intersectionPoint == lastPoint): streamInfo['measure'] = 0 if (intersectionPoint != startPoint and intersectionPoint != lastPoint): print('Error: NHD Flowline measure not calculated') streamInfo['measure'] = 'null' else: lastLineID = len(NHDFlowlinesCut) - 1 distToOutlet = round(geod.geometry_length(NHDFlowlinesCut[lastLineID]), 2) flowlineLength = round(geod.geometry_length(nhdFlowline), 2) streamInfo['measure'] = round((distToOutlet / flowlineLength) * 100, 2) print('calculated measure and reach') return streamInfo
def test_geometry_length__multipoint(): geod = Geod(ellps="WGS84") assert ( geod.geometry_length(MultiPoint([Point(1, 2), Point(3, 4), Point(5, 2)])) == 0 )
def test_geometry_length__point(): geod = Geod(ellps="WGS84") assert geod.geometry_length(Point(1, 2)) == 0
def main(config): data_path = config['paths']['data'] scratch_path = config['paths']['scratch'] edges = gpd.read_file((os.path.join(scratch_path, "road_africa","africa-road.gpkg")), layer="lines", ignore_fields=["waterway","aerialway","barrier","man_made","z_order","other_tags"]) print(edges) print("Done reading file") # From the geopackage file extract relevant roads highway_list = ['motorway','motorway_link', 'trunk','trunk_link', 'primary','primary_link', 'secondary','secondary_link', 'tertiary','tertiary_link'] edges = edges[edges.highway.isin(highway_list)] edges['highway'] = edges.progress_apply(lambda x: x.highway.replace('_link',''),axis=1) # Create network topology network = create_network_from_nodes_and_edges( None, edges, "road", out_fname, ) network.edges = network.edges.set_crs(epsg=4326) network.nodes = network.nodes.set_crs(epsg=4326) print (network.edges) print (network.nodes) print("Ready to export file") # Store the final road network in geopackage in the processed_path out_fname = os.path.join(data_path,"road/africa","africa-roads.gpkg") network.edges.to_file(out_fname, layer='edges', driver='GPKG') network.nodes.to_file(out_fname, layer='nodes', driver='GPKG') print("Done exporting, ready to add attributes") """Assign country info""" #Find the countries of the nodes and assign them to the node ID's, accordingly modify the edge ID's as well nodes = gpd.read_file(out_fname,layer='nodes') edges = gpd.read_file(out_fname,layer='edges') print("Done reading files") global_country_info = gpd.read_file(os.path.join(data_path, "Admin_boundaries", "gadm36_levels_gpkg", "gadm36_levels_continents.gpkg")) global_country_info = global_country_info.to_crs(epsg=4326) global_country_info = global_country_info.explode(ignore_index=True) global_country_info = global_country_info.sort_values(by="CONTINENT",ascending=True) # print (global_country_info) nodes["node_id"] = nodes.progress_apply(lambda x:"_".join(x["node_id"].split("_")[1:]),axis=1) nodes = nodes[["node_id","geometry"]] edges["edge_id"] = edges.progress_apply(lambda x:"_".join(x["edge_id"].split("_")[1:]),axis=1) edges["from_node"] = edges.progress_apply(lambda x:"_".join(x["from_node"].split("_")[1:]),axis=1) edges["to_node"] = edges.progress_apply(lambda x:"_".join(x["to_node"].split("_")[1:]),axis=1) edges = edges[["edge_id","from_node","to_node","highway","surface","maxspeed","lanes","bridge","length_km","geometry"]] # Set the crs edges = edges.set_crs(epsg=4326) nodes = nodes.set_crs(epsg=4326) nodes, edges = match_nodes_edges_to_countries(nodes,edges,global_country_info) print ("Done adding country info attributes") #edges.to_file(os.path.join(data_path,"road/africa","africa-roads.gpkg"), layer='edges', driver='GPKG') #nodes.to_file(os.path.join(data_path,"road/africa","africa-roads.gpkg"), layer='nodes', driver='GPKG') """Assign road attributes""" # Calculate and add length of line segments geod = Geod(ellps="WGS84") edges['length_m'] = edges.progress_apply(lambda x:float(geod.geometry_length(x.geometry)),axis=1) edges = edges.drop(['length_km'],axis=1) # Drop geometry for faster processing times edges_simple = edges.drop(['geometry'],axis=1) # Add road condition and material edges_simple['surface_material'] = edges_simple.progress_apply(lambda x:get_road_condition_surface(x),axis=1) edges_simple[['road_cond','material']] = edges_simple['surface_material'].progress_apply(pd.Series) edges_simple.drop('surface_material',axis=1,inplace=True) # Add number of lanes edges_simple['lanes'] = edges_simple.progress_apply(lambda x:get_road_lanes(x),axis=1) # Add road width width = 6.5 # Default carriageway width in meters for Africa, needs to be generalizable for global shoulder = 1.5 # Default shoulder width in meters for Africa, needs to be generalizable for global edges_simple['width_m'] = edges_simple.progress_apply(lambda x:float(x.lanes)*width + 2.0*shoulder,axis=1) # Assign min and max road speeds road_speeds = pd.read_excel(os.path.join(data_path,"road","global_road_speeds.xlsx"),sheet_name="global speeds") edges_simple = pd.merge(edges_simple,road_speeds,how="left",left_on=["from_iso"],right_on=["ISO_A3"]) edges_simple["min_max_speed"] = edges_simple.progress_apply(lambda x:assign_road_speeds(x),axis=1) edges_simple[["min_speed","max_speed"]] = edges_simple["min_max_speed"].progress_apply(pd.Series) edges_simple.drop(["min_max_speed","maxspeed"]+road_speeds.columns.values.tolist(),axis=1,inplace=True) print("Done adding road attributes") """Assign cost attributes""" # Assign rehabilitation costs rehab_costs = pd.read_excel(os.path.join(data_path,"costs","rehabilitation_costs.xlsx"), sheet_name = "road_costs") edges_simple["rehab_costs"] = edges_simple.progress_apply(lambda x:get_rehab_costs(x,rehab_costs),axis=1) edges_simple[["cost_min","cost_max","cost_unit"]] = edges_simple["rehab_costs"].progress_apply(pd.Series) edges_simple.drop("rehab_costs",axis=1,inplace=True) # Assign tariff costs cost_data = pd.read_csv(os.path.join(data_path,"costs","transport_costs.csv")) cost_data = cost_data.loc[cost_data['transport'] == "road"] cost_data.rename(columns = {'cost_km':'tariff_cost'}, inplace = True) edges_simple = pd.merge(edges_simple,cost_data[["from_iso3","tariff_cost"]],how="left",left_on=["from_iso"],right_on=["from_iso3"]) edges_simple["min_tariff"] = edges_simple.progress_apply(lambda x:float(x.tariff_cost) - (float(x.tariff_cost)*0.2),axis=1) edges_simple["max_tariff"] = edges_simple.progress_apply(lambda x:float(x.tariff_cost) + (float(x.tariff_cost)*0.2),axis=1) edges_simple.drop(["tariff_cost","from_iso3"],axis=1,inplace=True) edges_simple["tariff_cost_unit"] = "USD/ton-km" # Assign flow costs time_cost_factor = 0.49 edges_simple["min_flow_cost"] = (time_cost_factor*edges["length_m"]/1000)/edges_simple["max_speed"] + (edges_simple["min_tariff"]*edges_simple["length_m"]/1000) edges_simple["max_flow_cost"] = (time_cost_factor*edges["length_m"]/1000)/edges_simple["min_speed"] + (edges_simple["max_tariff"]*edges_simple["length_m"]/1000) edges_simple["flow_cost_unit"] = "USD/ton" print("Done adding cost attributes") # Prepare for export and finish edges = edges_simple.merge(edges[["edge_id","geometry"]],how = "left", on = "edge_id") edges = gpd.GeoDataFrame(edges,geometry="geometry",crs="EPSG:4326") # Add the component column edges, nodes = components(edges,nodes) print("Done adding components") print("Ready to export") edges.to_file(os.path.join(data_path,"road/africa","africa-roads-modified.gpkg"), layer='edges', driver='GPKG') nodes.to_file(os.path.join(data_path,"road/africa","africa-roads-modified.gpkg"), layer='nodes', driver='GPKG') print("Done.")
piece_dict = {} for edge in edge_dict: # Keep only unique break points break_points = edge_dict[edge].break_points unique_breaks = list(set(break_points)) # If all break points are the same, the edge is a point and we can skip if len(unique_breaks) == 1: print('Edge is a point: ', edge) continue way_id = str(edge_dict[edge].way) try: full_line = way_dict[way_id] line_length_ft = geod.geometry_length( full_line) * 3.28084 # meters to ft except KeyError: print('Error, No way available for ', way_id) continue # Discard break points that are at the ends of the line int_points = [] distances = [] line_start = False line_end = False for point in unique_breaks: point_geom = Point(point) distance = full_line.project(point_geom, normalized=True) if distance * line_length_ft <= midblock_tolerance: line_start = True
def points_to_meters(point_1, point_2): line_string = LineString([point_1, point_2]) geod = Geod(ellps="WGS84") return geod.geometry_length(line_string)