# FaPra Algorithms on OSM Data This repository contains implementations for the Fachpraktikum Algorithms on OSM Data. The code is written in Rust, a stable rust compiler and `cargo`, the rust build tool/package manager is required. # Building simply run `cargo build --release` to build release versions of all binaries. # Tasks ## Task 1 There is no real implementation work for task 1, next! ## Task 2 + Task 3 + Task 4 Reading the data from an OSM PDF file and converting it to a graph is done in `src/bin/generate_grid.rs`. The implementation of the spherical point in polygon test is done in `src/polygon.rs` with the function `contains()`. There is one polygon in the graph, for which no valid outside polygon can be found. I did not have the time to investigate this further. ### Extracting Coastlines from the PBF file The code uses the osmpbfreader crate. Sadly this module uses ~10GB of memory to extract the data from the PBF file with all the coastlines. So far I did not have time to look into what happens there. ### Point in Polygon The test by Bevis and Chatelain is implemented. Instead of using a point that is inside the polygon a point outside of the polygon is used, because here we can simply specify several "well-known" outside points that are somewhere in the ocean and therefore are outside of every polygon. ### Grid Graph The Grid Graph is implemented in `gridgraph.rs`. A regular grid graph can be generated with the `generate_regular_grid` function. Import and Export from/to a file can be done with the `from_fmi_file` and `write_fmi_file` functions. ## Task 5 ### Dijkstra Benchmarks The dijkstras algorithm is implenented in `gridgraph.rs`. It uses a Heap to store the nodes. ## Task 6 The UI is a Web-UI based on leaflet. To start it, run `task6` with a .fmi file as a graph layout and a set of landmarks (see Task 7 for details). The start and end nodes can be placed on arbitrary positions and an algorithm searches for the closes grid node and then runs the Routing. The webserver listens on http://localhost:8000 Currently there is a display bug when routes wrap around the globe at 180 degrees longitude. Instead of continuing the line as expected the line is drawn around the globe in the "wrong" direction. This is however just a display bug, the route itself is correct. ## Task 7 I implemented ALT, as described in [1]. Additionally A\* is available with a simple, unoptimized haversine distance as the heuristic. ### Landmarks for ALT currently 3 different landmark generation methods are available - random selection - greedy, distance-maximizing selection - manual selection (from a GeoJSON file) These can be generated with the `gen_landmarks_random`, `gen_landmarks_greedy` and `gen_landmarks_geojson` binaries. The random and greedy methods take the number of landmarks to select from a parameter. A handy wrapper for that can be found as a Python script in `utils/generate_landmarks.py` that generates landmarks for 4, 8, 16, 32 and 64 landmarks, both greedy and random. # Running the benchmarks First a set of queries is needed. This can be done with the `generate_benchmark_targets --graph > targets.json`. This generates 1000 random, distinct source and destination pairs. The `--amount` parameter allows to adjust the number of pairs generated. The actual benchmark is located in `benchmark`. It needs a set of queries and a graph. If the `--dijkstra` option is given it runs Dijkstras algorithm. If the `--astar` option is given it runs A\* with the haversine distance If `--landmarks ` is given it runs ALT with that landmark file. By setting `--alt_best_size ` one can select how many of the landmarks are used to answer the query. The benchmark prints out how many nodes were popped from the heap for each run and the average time per route. [1] Computing the Shortest Path: A* meets Graph Theory, A. Goldberg and C. Harrelson, Microsoft Research, Technical Report MSR-TR-2004-24, 2004