diff --git a/README.rst b/README.rst index 655dbafd..8b571db5 100644 --- a/README.rst +++ b/README.rst @@ -115,6 +115,7 @@ Command line help [--initial-zoom N] [--max-zoom N] [--export-features EXPORT_FILE] [--export-neurons EXPORT_FILE] [--export-svg EXPORT_FILE] [--single-file {celldl,svg}] + [--path-arrows] --output OUTPUT --source SOURCE Generate a flatmap from its source manifest. @@ -145,6 +146,7 @@ Command line help Create a SPARC Dataset containing the map's sources and the generated map --sckan-version {production,staging} Overide version of SCKAN specified by map's manifest + --path-arrows Render arrows at the terminal nodes of paths Diagnostics: --authoring For use when checking a new map: highlight incomplete diff --git a/mapmaker/__main__.py b/mapmaker/__main__.py index 0235e4bc..e6e6ad86 100644 --- a/mapmaker/__main__.py +++ b/mapmaker/__main__.py @@ -63,6 +63,8 @@ def arg_parser(): help="Create a SPARC Dataset containing the map's sources and the generated map") generation_options.add_argument('--sckan-version', dest='sckanVersion', choices=['production', 'staging'], help="Overide version of SCKAN specified by map's manifest") + generation_options.add_argument('--path-arrows', dest='pathArrows', action='store_true', + help="Render arrows at the terminal nodes of paths") debug_options = parser.add_argument_group('Diagnostics') debug_options.add_argument('--authoring', action='store_true', diff --git a/mapmaker/routing/__init__.py b/mapmaker/routing/__init__.py index 094672f2..3c7c3b52 100644 --- a/mapmaker/routing/__init__.py +++ b/mapmaker/routing/__init__.py @@ -1482,18 +1482,19 @@ def set_direction(upstream_node): route_graph.nodes[closest_feature_id]['type'] = 'terminal' route_graph.nodes[n_features[0].id].update(set_properties_from_feature_id(n_features[0].id)) - # need to delete edges that is already covered by centerline + # checking looping paths, remove if connectivity_graph doesn't require it + # this could be caused by unnecesary centrelines for edge in new_edge_dicts: - for p in list(nx.all_simple_paths(tmp_route_graph, source=edge[0], target=edge[1])): - if len(p) > 2: - for i in range(len(p)-1): - tmp_graph = nx.Graph(route_graph) - if (p[i], p[i+1]) not in route_graph.edges: - continue - else: - tmp_graph.remove_edge(p[i], p[i+1]) - if nx.is_connected(nx.Graph(tmp_graph.edges)): - route_graph.remove_edge(p[i], p[i+1]) + if len(simple_paths:=sorted(list(nx.all_simple_paths(tmp_route_graph, source=edge[0], target=edge[1])), key=len, reverse=True)) > 1: + matching_nodes = { + n:sp for sp in simple_paths + for n, data in connectivity_graph.nodes(data=True) + if set(data.get('features', data.get('used', []))) & set(sp) + } + if len(mn_keys:=list(matching_nodes.keys())) == 2: + simple_node_paths = list(nx.all_simple_edge_paths(connectivity_graph, source=mn_keys[0], target=mn_keys[1])) + while len(simple_paths) > len(simple_node_paths): + route_graph.remove_edges_from([simple_paths.pop()]) centreline_ids = set() for node_0, node_1, edge_dict in nx.Graph(route_graph).edges(data=True): diff --git a/mapmaker/routing/routedpath.py b/mapmaker/routing/routedpath.py index 3871447a..9d59ca99 100644 --- a/mapmaker/routing/routedpath.py +++ b/mapmaker/routing/routedpath.py @@ -417,14 +417,15 @@ def connect_gap(node, node_points, iscentreline=False): # Draw paths to terminal nodes def draw_arrow(start_point, end_point, path_id, path_source): - heading = (end_point - start_point).angle - end_point -= BezierPoint.fromAngle(heading)*0.9*ARROW_LENGTH - path_geometry[path_id].append(GeometricShape.arrow(end_point, heading, ARROW_LENGTH, properties={ - 'type': 'arrow', - 'path-id': path_id, - 'source': path_source, - 'label': self.__graph.graph.get('label') - })) + if settings.get('pathArrows', False): + heading = (end_point - start_point).angle + end_point -= BezierPoint.fromAngle(heading)*0.9*ARROW_LENGTH + path_geometry[path_id].append(GeometricShape.arrow(end_point, heading, ARROW_LENGTH, properties={ + 'type': 'arrow', + 'path-id': path_id, + 'source': path_source, + 'label': self.__graph.graph.get('label') + })) def draw_line(node_0, node_1, tolerance=0.1, separation=2000): start_coords = self.__graph.nodes[node_0]['geometry'].centroid.coords[0] @@ -479,7 +480,7 @@ def draw_line(node_0, node_1, tolerance=0.1, separation=2000): end_coords = self.__graph.nodes[terminal_node]['geometry'].centroid.coords[0] end_point = coords_to_point(end_coords) heading = (end_point - start_point).angle - bz_end_point = end_point - BezierPoint.fromAngle(heading)*0.9*ARROW_LENGTH + bz_end_point = (end_point - BezierPoint.fromAngle(heading) * 0.9 * ARROW_LENGTH) if settings.get('pathArrows', False) else end_point bz = bezier_connect(start_point, bz_end_point, angle, heading) path_geometry[path_id].append(GeometricShape( bezier_to_linestring(bz), {