Possibility to save gpx
Closed this issue ยท 15 comments
Hi bartsaintgermain!,
Thanks for raising an issue! The file is in XML format so all you need to do is to hit Ctrl + S
as save it as e.g. .gpx
.
I tried to add download
flied to do <a>
as is recommended. Unfortunately, it is not working and I assume because the GPX
file isn't on the same domain ๐
[path] that resolves to an URL on the same origin. That means the page and the file must share the same domain, subdomain, protocol (HTTP vs. HTTPS), and port (if specified). Exceptions are blob: and data: (which always work), and file: (which never works). (https://stackoverflow.com/a/18678698)
In the next release, I will try to take deeper look into :)
Matej
Is this also possible when running locally. I did succeed in generating the png files but could not find the gpx/xml file.
Hmm, interesting. It is created as XML
file so when you download it, you should get XML
and not png.
I have the same question. If I download the python code and run the program locally I can generate the .png's given in the example of "The Grange". However, the code as given does not generate a .gpx file. The website generates a .gpx file so it must be possible to generate one. How can we generate a .gpx in the vein of the code example you provide. Thanks.
I think that understand your question now. Sure, the jupyter notebook / the Grange example doesn't have the .gpx
output.
You can do it simply by converting networkx
nodes into geo coordinates, e.g. using this function convert_final_path_to_coordinates(org_graph, final_path)
and using a newly added gpx_formatter.py
. Putting all together, you can try something like:
from libs.tools import *
from libs.gpx_formatter import TEMPLATE, TRACE_POINT
...
# List all edges of the extended graph including original edges and edges from minimal matching
single_edges = [(u, v) for u, v, k in graph.edges]
added_edges = get_shortest_paths(graph, matched_edges_with_weights)
edges = map_osmnx_edges2integers(graph, single_edges + added_edges)
# Finds the Eulerian path
network = Network(len(graph.nodes), edges, weighted=True)
eulerian_path = hierholzer(network)
converted_eulerian_path = convert_integer_path2osmnx_nodes(eulerian_path, graph.nodes())
double_edge_heap = get_double_edge_heap(org_graph)
# Finds the final path with edge IDs
final_path = convert_path(graph, converted_eulerian_path, double_edge_heap)
coordinates_path = convert_final_path_to_coordinates(org_graph, final_path)
# Route statistics from OSMnx
ex = ox.extended_stats(org_graph, ecc=True)
center_node = org_graph.nodes[ex["center"][0]]
trace_points = "\n\t\t\t".join([TRACE_POINT.format(
lat=lat, lon=lon, id=i, timestamp=datetime.now().isoformat()
) for i, (lat, lon) in enumerate(coordinates_path)])
gpx_payload = TEMPLATE.format(
name="Name your everystreet route",
trace_points=trace_points,
center_lat=center_node["y"],
center_lon=center_node["x"]
)
with open("gpx_output.gpx", "w") as f:
f.write(gpx_payload)
I believe this could work ๐
Thank you so much! That works great. The .xml format doesn't play nice with the mapping software I am using, but plugging it into this website : https://mygeodata.cloud/converter/mapfactor-to-gpx generates a .gpx file that works.
I also had to use datetime.now() -> datetime.datetime.now().
Glad to hear that! Oh yeah, I could name it open("gpx_output.gpx", "w")
and it would work.
BTW, did you know that you can generate the GPX
file on http://www.everystreetchallenge.com?
Thx.
Would be great to generate from site but quickly hit on 3km2 limit.
I agree that the 3km^2 limit is annoying, on the other hand I think you will understand it is a webserver and the algorithm is a bit "heavy" ๐
Maybe different question, I guess you have tried to find a route on larger area and you saw that it takes a while, it is basically undoable to generate larger areas such as whole cities. I tired to generate Edinburgh and after an hour I had to kill it. I believe that some optimisation (such as multiprocessing) could help. What would be a decent area size for you as a user? Or what is the area that you are trying to generate?
sure, I fully understand the limit.
my area is about 50m2 but mostly rural area. I guess the number of streets and intersections are also determining the complexity.
Yeah, the area it self isn't a problem, even the number of nodes / edges, but the issue are odd-degree nodes. I thought, it might be simpler to and easier to understand to restrict it based on the area size than based on the number of odd-degree nodes.
Hello @matejker,
Your job on that CPP is great, thanks a lot ! However, I've tried many things to save the route as GPX on www.everystreetchallenge.com (ctrl+s, save as, source code display, both on PC & MAC, etc.), but I cannot get anything else than HTML or TXT. Did I miss something ? Because that wold be SO useful !
JB
did you know that you can generate the
GPX
file on http://www.everystreetchallenge.com?
I think that functionality might be broken? At least just like @1J2B I can't seem to find a way to export the result.
I think that understand your question now. Sure, the jupyter notebook / the Grange example doesn't have the
.gpx
output. You can do it simply by convertingnetworkx
nodes into geo coordinates, e.g. using this functionconvert_final_path_to_coordinates(org_graph, final_path)
and using a newly addedgpx_formatter.py
. Putting all together, you can try something like:from libs.tools import * from libs.gpx_formatter import TEMPLATE, TRACE_POINT ... # List all edges of the extended graph including original edges and edges from minimal matching single_edges = [(u, v) for u, v, k in graph.edges] added_edges = get_shortest_paths(graph, matched_edges_with_weights) edges = map_osmnx_edges2integers(graph, single_edges + added_edges) # Finds the Eulerian path network = Network(len(graph.nodes), edges, weighted=True) eulerian_path = hierholzer(network) converted_eulerian_path = convert_integer_path2osmnx_nodes(eulerian_path, graph.nodes()) double_edge_heap = get_double_edge_heap(org_graph) # Finds the final path with edge IDs final_path = convert_path(graph, converted_eulerian_path, double_edge_heap) coordinates_path = convert_final_path_to_coordinates(org_graph, final_path) # Route statistics from OSMnx ex = ox.extended_stats(org_graph, ecc=True) center_node = org_graph.nodes[ex["center"][0]] trace_points = "\n\t\t\t".join([TRACE_POINT.format( lat=lat, lon=lon, id=i, timestamp=datetime.now().isoformat() ) for i, (lat, lon) in enumerate(coordinates_path)]) gpx_payload = TEMPLATE.format( name="Name your everystreet route", trace_points=trace_points, center_lat=center_node["y"], center_lon=center_node["x"] ) with open("gpx_output.gpx", "w") as f: f.write(gpx_payload)I believe this could work ๐
Hi Thanks for this fun tool.
In order to get this GPX output i had to (in addition to install scipy):
- add "import datetime"
- add an extra "datetime." to get the following:
lat=lat, lon=lon, id=i, timestamp=datetime.datetime.now().isoformat()
find an example (replace .txt by .ipynb)
example.txt
Function extended_stats was deprecated for a while before it was eventually removed.
use NetworkX :
from libs.gpx_formatter import TEMPLATE, TRACE_POINT
from datetime import datetime
...
# List all edges of the extended graph including original edges and edges from minimal matching
single_edges = [(u, v) for u, v, k in graph.edges]
added_edges = get_shortest_paths(graph, matched_edges_with_weights)
edges = map_osmnx_edges2integers(graph, single_edges + added_edges)
# Finds the Eulerian path
network = Network(len(graph.nodes), edges, weighted=True)
eulerian_path = hierholzer(network)
converted_eulerian_path = convert_integer_path2osmnx_nodes(eulerian_path, graph.nodes())
double_edge_heap = get_double_edge_heap(org_graph)
# Finds the final path with edge IDs
final_path = convert_path(graph, converted_eulerian_path, double_edge_heap)
coordinates_path = convert_final_path_to_coordinates(org_graph, final_path)
eccentricity = nx.eccentricity(graph)
center = nx.center(graph)
center_node = graph.nodes[center[0]]
trace_points = "\n\t\t\t".join([TRACE_POINT.format(
lat=lat, lon=lon, id=i, timestamp=datetime.now().isoformat()
) for i, (lat, lon) in enumerate(coordinates_path)])
gpx_payload = TEMPLATE.format(
name="Name your everystreet route",
trace_points=trace_points,
center_lat=center_node["y"],
center_lon=center_node["x"]
)
with open("gpx_output.gpx", "w") as f:
f.write(gpx_payload)