Repository files navigation

Cyclops - an alternative route planning tool for bicycles

Cyclops finds alternative routes between two points using multiple metrics. Each of the paths is optimal for some combination of the metrics and sufficiently different from the others according to user preference. Alternative routes from Pforzheim to Stuttgart

It does this fast by using the Dijkstra speed-up technique multicriteria contraction hierarchies.

Cyclops was initially implemented for bicycle routes and three specific metrics. Although the Cyclops back end is capable of handling other metrics and a different number of metrics its front end is only designed for this use case and would need adaption for a different one.

Building

To Build Cyclops first clone it and change into its directory:

git clone --recursive https://github.com/lesstat/cyclops
cd cyclops

Then create a build directory for cmake and run cmake and make.

mkdir build
cd build
cmake ..
make -j

Usage

The main executable of Cyclops is cyclops. It has the following cli options:

$ ./build/cyclops -h
-h [ --help ] prints help message
loading options:
-t [ --text ] arg load graph from text file
-b [ --bin ] arg load graph form binary file
--zi input text file is gzipped
-d [ --dimension ] arg Dimension of loaded Graph
actions:
--save arg save graph to binary file
--test runs normal dijkstra and CH dijktra for comparison
-w [ --web ] start webserver for interaction via browser

It needs exactly one of the first two in the loading category to load a graph and at least one of the second category. --zi can be combined with the -t option to directly read zip compressed graph files in text format. -d sets the dimension of the loaded graph. Default is 3. Dimensions one to three are supported currently. Larger Dimension can be added easily see below.

The actions are executed in the order they are displayed above.

--save prompts the application write the graph to a binary file for faster loading (no text parsing necessary).

--test executes 1,000 random source-target queries with Dijkstra and CH-Dijkstra, assures that they output the same path and prints the speed-up at the end.

--web starts a web server for interactive use. Cyclops expects a directory named web with the contents for the web interface at the current working directory (not the directory the executable is located in). Starting from the root directory of the repository is currently mandatory for the web interface. The Web interface is available at http://localhost:8080/web

Different Number of Metrics

Although Cyclops was initially implemented to handle exactly three metrics, it was adapted to handle an arbitrary number of metrics. For best performance the number of metrics is needed at compile time. If you want to work with more metrics change the switch statement at the bottom of the main function in main.cpp

For four metrics the following lines would need to be added:

case4: {
return run<4>(vm, loadFileName, saveFileName);
break;
}

Graph Data

Cyclops can read road graphs in two different formats. The important one is a text format. The other one is a binary format which Cyclops can write from any valid input graph and read again. It is used for faster reading and writing of graphs which should not be modified any more.

The text format consists of a header and a body.

Header

The header starts with an arbitrary number of lines reserved for comments. These lines start with and #. They are followed by a blank line and afterwards three lines defining the contents of the file:

  • Dimension of the cost vector
  • Number of nodes
  • Number of edges

A header could look like this:

# Creation date: 02.03.2018
# Edge Costs: length, travel time, positive height ascent
3
8456123
17987123

Which means there is a vector of size three assigned to every edge. There are 8,456,123 nodes in the graph and 17,987,123 edges.

As mentioned above Cyclops needs to be compiled with the right dimension for different dimensions to work. This will be checked when the graph is read.

Nodes

Immediately after the header (without a blank line) follows the data for all nodes, one node per line:

0 125799 53.0749415 8.7868047 3.4728513520111997 0

Those values are:

<internal id> <osmid> <latitude> <longitude> <height> <CH-Level>

No two nodes are allowed to have the same internal id. The CH-Level is important for the speeding up the shortest path search. A Ch-Graph can for example be constructed from a normal graph by my multi-ch-constructor.

Cyclops works with a normal graph too, but slowly :-)

Edges

After the last node the edges of the graph start. An edge looks like this:

22 104289 6 0.17316000000255372 1.5 -1 -1

which stands for:

<internal source node id> <internal destinantion node id> <cost 1>
<cost 2> .. <cost dimension> <replaced edge id 1> <replaced edge id 2>

Edges are always one way. The replaced edge ids are for shortcut edges in a CH-Graph. Normal edges don't replace other edges and there for have -1 as replaced edge id. An edge is assigned an internal id by the placement in the file. The first edge has id 0, the second id 1, and so on.

About

Alternative route planning tool (for bicycle)

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Cyclops - an alternative route planning tool for bicycles

Cyclops finds alternative routes between two points using multiple metrics. Each of the paths is optimal for some combination of the metrics and sufficiently different from the others according to user preference. Alternative routes from Pforzheim to Stuttgart

It does this fast by using the Dijkstra speed-up technique multicriteria contraction hierarchies.

Cyclops was initially implemented for bicycle routes and three specific metrics. Although the Cyclops back end is capable of handling other metrics and a different number of metrics its front end is only designed for this use case and would need adaption for a different one.

Building

To Build Cyclops first clone it and change into its directory:

git clone --recursive https://github.com/lesstat/cyclops
cd cyclops

Then create a build directory for cmake and run cmake and make.

mkdir build
cd build
cmake ..
make -j

Usage

The main executable of Cyclops is cyclops. It has the following cli options:

$ ./build/cyclops -h
-h [ --help ] prints help message
loading options:
-t [ --text ] arg load graph from text file
-b [ --bin ] arg load graph form binary file
--zi input text file is gzipped
-d [ --dimension ] arg Dimension of loaded Graph
actions:
--save arg save graph to binary file
--test runs normal dijkstra and CH dijktra for comparison
-w [ --web ] start webserver for interaction via browser

It needs exactly one of the first two in the loading category to load a graph and at least one of the second category. --zi can be combined with the -t option to directly read zip compressed graph files in text format. -d sets the dimension of the loaded graph. Default is 3. Dimensions one to three are supported currently. Larger Dimension can be added easily see below.

The actions are executed in the order they are displayed above.

--save prompts the application write the graph to a binary file for faster loading (no text parsing necessary).

--test executes 1,000 random source-target queries with Dijkstra and CH-Dijkstra, assures that they output the same path and prints the speed-up at the end.

--web starts a web server for interactive use. Cyclops expects a directory named web with the contents for the web interface at the current working directory (not the directory the executable is located in). Starting from the root directory of the repository is currently mandatory for the web interface. The Web interface is available at http://localhost:8080/web

Different Number of Metrics

Although Cyclops was initially implemented to handle exactly three metrics, it was adapted to handle an arbitrary number of metrics. For best performance the number of metrics is needed at compile time. If you want to work with more metrics change the switch statement at the bottom of the main function in main.cpp

For four metrics the following lines would need to be added:

case4: {
return run<4>(vm, loadFileName, saveFileName);
break;
}

Graph Data

Cyclops can read road graphs in two different formats. The important one is a text format. The other one is a binary format which Cyclops can write from any valid input graph and read again. It is used for faster reading and writing of graphs which should not be modified any more.

The text format consists of a header and a body.

Header

The header starts with an arbitrary number of lines reserved for comments. These lines start with and #. They are followed by a blank line and afterwards three lines defining the contents of the file:

  • Dimension of the cost vector
  • Number of nodes
  • Number of edges

A header could look like this:

# Creation date: 02.03.2018
# Edge Costs: length, travel time, positive height ascent
3
8456123
17987123

Which means there is a vector of size three assigned to every edge. There are 8,456,123 nodes in the graph and 17,987,123 edges.

As mentioned above Cyclops needs to be compiled with the right dimension for different dimensions to work. This will be checked when the graph is read.

Nodes

Immediately after the header (without a blank line) follows the data for all nodes, one node per line:

0 125799 53.0749415 8.7868047 3.4728513520111997 0

Those values are:

<internal id> <osmid> <latitude> <longitude> <height> <CH-Level>

No two nodes are allowed to have the same internal id. The CH-Level is important for the speeding up the shortest path search. A Ch-Graph can for example be constructed from a normal graph by my multi-ch-constructor.

Cyclops works with a normal graph too, but slowly :-)

Edges

After the last node the edges of the graph start. An edge looks like this:

22 104289 6 0.17316000000255372 1.5 -1 -1

which stands for:

<internal source node id> <internal destinantion node id> <cost 1>
<cost 2> .. <cost dimension> <replaced edge id 1> <replaced edge id 2>

Edges are always one way. The replaced edge ids are for shortcut edges in a CH-Graph. Normal edges don't replace other edges and there for have -1 as replaced edge id. An edge is assigned an internal id by the placement in the file. The first edge has id 0, the second id 1, and so on.

About

Alternative route planning tool (for bicycle)

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Cyclops - an alternative route planning tool for bicycles

Cyclops finds alternative routes between two points using multiple metrics. Each of the paths is optimal for some combination of the metrics and sufficiently different from the others according to user preference. Alternative routes from Pforzheim to Stuttgart

It does this fast by using the Dijkstra speed-up technique multicriteria contraction hierarchies.

Cyclops was initially implemented for bicycle routes and three specific metrics. Although the Cyclops back end is capable of handling other metrics and a different number of metrics its front end is only designed for this use case and would need adaption for a different one.

Building

To Build Cyclops first clone it and change into its directory:

git clone --recursive https://github.com/lesstat/cyclops
cd cyclops

Then create a build directory for cmake and run cmake and make.

mkdir build
cd build
cmake ..
make -j

Usage

The main executable of Cyclops is cyclops. It has the following cli options:

$ ./build/cyclops -h
-h [ --help ] prints help message
loading options:
-t [ --text ] arg load graph from text file
-b [ --bin ] arg load graph form binary file
--zi input text file is gzipped
-d [ --dimension ] arg Dimension of loaded Graph
actions:
--save arg save graph to binary file
--test runs normal dijkstra and CH dijktra for comparison
-w [ --web ] start webserver for interaction via browser

It needs exactly one of the first two in the loading category to load a graph and at least one of the second category. --zi can be combined with the -t option to directly read zip compressed graph files in text format. -d sets the dimension of the loaded graph. Default is 3. Dimensions one to three are supported currently. Larger Dimension can be added easily see below.

The actions are executed in the order they are displayed above.

--save prompts the application write the graph to a binary file for faster loading (no text parsing necessary).

--test executes 1,000 random source-target queries with Dijkstra and CH-Dijkstra, assures that they output the same path and prints the speed-up at the end.

--web starts a web server for interactive use. Cyclops expects a directory named web with the contents for the web interface at the current working directory (not the directory the executable is located in). Starting from the root directory of the repository is currently mandatory for the web interface. The Web interface is available at http://localhost:8080/web

Different Number of Metrics

Although Cyclops was initially implemented to handle exactly three metrics, it was adapted to handle an arbitrary number of metrics. For best performance the number of metrics is needed at compile time. If you want to work with more metrics change the switch statement at the bottom of the main function in main.cpp

For four metrics the following lines would need to be added:

case4: {
return run<4>(vm, loadFileName, saveFileName);
break;
}

Graph Data

Cyclops can read road graphs in two different formats. The important one is a text format. The other one is a binary format which Cyclops can write from any valid input graph and read again. It is used for faster reading and writing of graphs which should not be modified any more.

The text format consists of a header and a body.

Header

The header starts with an arbitrary number of lines reserved for comments. These lines start with and #. They are followed by a blank line and afterwards three lines defining the contents of the file:

  • Dimension of the cost vector
  • Number of nodes
  • Number of edges

A header could look like this:

# Creation date: 02.03.2018
# Edge Costs: length, travel time, positive height ascent
3
8456123
17987123

Which means there is a vector of size three assigned to every edge. There are 8,456,123 nodes in the graph and 17,987,123 edges.

As mentioned above Cyclops needs to be compiled with the right dimension for different dimensions to work. This will be checked when the graph is read.

Nodes

Immediately after the header (without a blank line) follows the data for all nodes, one node per line:

0 125799 53.0749415 8.7868047 3.4728513520111997 0

Those values are:

<internal id> <osmid> <latitude> <longitude> <height> <CH-Level>

No two nodes are allowed to have the same internal id. The CH-Level is important for the speeding up the shortest path search. A Ch-Graph can for example be constructed from a normal graph by my multi-ch-constructor.

Cyclops works with a normal graph too, but slowly :-)

Edges

After the last node the edges of the graph start. An edge looks like this:

22 104289 6 0.17316000000255372 1.5 -1 -1

which stands for:

<internal source node id> <internal destinantion node id> <cost 1>
<cost 2> .. <cost dimension> <replaced edge id 1> <replaced edge id 2>

Edges are always one way. The replaced edge ids are for shortcut edges in a CH-Graph. Normal edges don't replace other edges and there for have -1 as replaced edge id. An edge is assigned an internal id by the placement in the file. The first edge has id 0, the second id 1, and so on.

About

Alternative route planning tool (for bicycle)

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Cyclops - an alternative route planning tool for bicycles

Cyclops finds alternative routes between two points using multiple metrics. Each of the paths is optimal for some combination of the metrics and sufficiently different from the others according to user preference. Alternative routes from Pforzheim to Stuttgart

It does this fast by using the Dijkstra speed-up technique multicriteria contraction hierarchies.

Cyclops was initially implemented for bicycle routes and three specific metrics. Although the Cyclops back end is capable of handling other metrics and a different number of metrics its front end is only designed for this use case and would need adaption for a different one.

Building

To Build Cyclops first clone it and change into its directory:

git clone --recursive https://github.com/lesstat/cyclops
cd cyclops

Then create a build directory for cmake and run cmake and make.

mkdir build
cd build
cmake ..
make -j

Usage

The main executable of Cyclops is cyclops. It has the following cli options:

$ ./build/cyclops -h
-h [ --help ] prints help message
loading options:
-t [ --text ] arg load graph from text file
-b [ --bin ] arg load graph form binary file
--zi input text file is gzipped
-d [ --dimension ] arg Dimension of loaded Graph
actions:
--save arg save graph to binary file
--test runs normal dijkstra and CH dijktra for comparison
-w [ --web ] start webserver for interaction via browser

It needs exactly one of the first two in the loading category to load a graph and at least one of the second category. --zi can be combined with the -t option to directly read zip compressed graph files in text format. -d sets the dimension of the loaded graph. Default is 3. Dimensions one to three are supported currently. Larger Dimension can be added easily see below.

The actions are executed in the order they are displayed above.

--save prompts the application write the graph to a binary file for faster loading (no text parsing necessary).

--test executes 1,000 random source-target queries with Dijkstra and CH-Dijkstra, assures that they output the same path and prints the speed-up at the end.

--web starts a web server for interactive use. Cyclops expects a directory named web with the contents for the web interface at the current working directory (not the directory the executable is located in). Starting from the root directory of the repository is currently mandatory for the web interface. The Web interface is available at http://localhost:8080/web

Different Number of Metrics

Although Cyclops was initially implemented to handle exactly three metrics, it was adapted to handle an arbitrary number of metrics. For best performance the number of metrics is needed at compile time. If you want to work with more metrics change the switch statement at the bottom of the main function in main.cpp

For four metrics the following lines would need to be added:

case4: {
return run<4>(vm, loadFileName, saveFileName);
break;
}

Graph Data

Cyclops can read road graphs in two different formats. The important one is a text format. The other one is a binary format which Cyclops can write from any valid input graph and read again. It is used for faster reading and writing of graphs which should not be modified any more.

The text format consists of a header and a body.

Header

The header starts with an arbitrary number of lines reserved for comments. These lines start with and #. They are followed by a blank line and afterwards three lines defining the contents of the file:

  • Dimension of the cost vector
  • Number of nodes
  • Number of edges

A header could look like this:

# Creation date: 02.03.2018
# Edge Costs: length, travel time, positive height ascent
3
8456123
17987123

Which means there is a vector of size three assigned to every edge. There are 8,456,123 nodes in the graph and 17,987,123 edges.

As mentioned above Cyclops needs to be compiled with the right dimension for different dimensions to work. This will be checked when the graph is read.

Nodes

Immediately after the header (without a blank line) follows the data for all nodes, one node per line:

0 125799 53.0749415 8.7868047 3.4728513520111997 0

Those values are:

<internal id> <osmid> <latitude> <longitude> <height> <CH-Level>

No two nodes are allowed to have the same internal id. The CH-Level is important for the speeding up the shortest path search. A Ch-Graph can for example be constructed from a normal graph by my multi-ch-constructor.

Cyclops works with a normal graph too, but slowly :-)

Edges

After the last node the edges of the graph start. An edge looks like this:

22 104289 6 0.17316000000255372 1.5 -1 -1

which stands for:

<internal source node id> <internal destinantion node id> <cost 1>
<cost 2> .. <cost dimension> <replaced edge id 1> <replaced edge id 2>

Edges are always one way. The replaced edge ids are for shortcut edges in a CH-Graph. Normal edges don't replace other edges and there for have -1 as replaced edge id. An edge is assigned an internal id by the placement in the file. The first edge has id 0, the second id 1, and so on.

About

Alternative route planning tool (for bicycle)

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Cyclops - an alternative route planning tool for bicycles

Cyclops finds alternative routes between two points using multiple metrics. Each of the paths is optimal for some combination of the metrics and sufficiently different from the others according to user preference. Alternative routes from Pforzheim to Stuttgart

It does this fast by using the Dijkstra speed-up technique multicriteria contraction hierarchies.

Cyclops was initially implemented for bicycle routes and three specific metrics. Although the Cyclops back end is capable of handling other metrics and a different number of metrics its front end is only designed for this use case and would need adaption for a different one.

Building

To Build Cyclops first clone it and change into its directory:

git clone --recursive https://github.com/lesstat/cyclops
cd cyclops

Then create a build directory for cmake and run cmake and make.

mkdir build
cd build
cmake ..
make -j

Usage

The main executable of Cyclops is cyclops. It has the following cli options:

$ ./build/cyclops -h
-h [ --help ] prints help message
loading options:
-t [ --text ] arg load graph from text file
-b [ --bin ] arg load graph form binary file
--zi input text file is gzipped
-d [ --dimension ] arg Dimension of loaded Graph
actions:
--save arg save graph to binary file
--test runs normal dijkstra and CH dijktra for comparison
-w [ --web ] start webserver for interaction via browser

It needs exactly one of the first two in the loading category to load a graph and at least one of the second category. --zi can be combined with the -t option to directly read zip compressed graph files in text format. -d sets the dimension of the loaded graph. Default is 3. Dimensions one to three are supported currently. Larger Dimension can be added easily see below.

The actions are executed in the order they are displayed above.

--save prompts the application write the graph to a binary file for faster loading (no text parsing necessary).

--test executes 1,000 random source-target queries with Dijkstra and CH-Dijkstra, assures that they output the same path and prints the speed-up at the end.

--web starts a web server for interactive use. Cyclops expects a directory named web with the contents for the web interface at the current working directory (not the directory the executable is located in). Starting from the root directory of the repository is currently mandatory for the web interface. The Web interface is available at http://localhost:8080/web

Different Number of Metrics

Although Cyclops was initially implemented to handle exactly three metrics, it was adapted to handle an arbitrary number of metrics. For best performance the number of metrics is needed at compile time. If you want to work with more metrics change the switch statement at the bottom of the main function in main.cpp

For four metrics the following lines would need to be added:

case4: {
return run<4>(vm, loadFileName, saveFileName);
break;
}

Graph Data

Cyclops can read road graphs in two different formats. The important one is a text format. The other one is a binary format which Cyclops can write from any valid input graph and read again. It is used for faster reading and writing of graphs which should not be modified any more.

The text format consists of a header and a body.

Header

The header starts with an arbitrary number of lines reserved for comments. These lines start with and #. They are followed by a blank line and afterwards three lines defining the contents of the file:

  • Dimension of the cost vector
  • Number of nodes
  • Number of edges

A header could look like this:

# Creation date: 02.03.2018
# Edge Costs: length, travel time, positive height ascent
3
8456123
17987123

Which means there is a vector of size three assigned to every edge. There are 8,456,123 nodes in the graph and 17,987,123 edges.

As mentioned above Cyclops needs to be compiled with the right dimension for different dimensions to work. This will be checked when the graph is read.

Nodes

Immediately after the header (without a blank line) follows the data for all nodes, one node per line:

0 125799 53.0749415 8.7868047 3.4728513520111997 0

Those values are:

<internal id> <osmid> <latitude> <longitude> <height> <CH-Level>

No two nodes are allowed to have the same internal id. The CH-Level is important for the speeding up the shortest path search. A Ch-Graph can for example be constructed from a normal graph by my multi-ch-constructor.

Cyclops works with a normal graph too, but slowly :-)

Edges

After the last node the edges of the graph start. An edge looks like this:

22 104289 6 0.17316000000255372 1.5 -1 -1

which stands for:

<internal source node id> <internal destinantion node id> <cost 1>
<cost 2> .. <cost dimension> <replaced edge id 1> <replaced edge id 2>

Edges are always one way. The replaced edge ids are for shortcut edges in a CH-Graph. Normal edges don't replace other edges and there for have -1 as replaced edge id. An edge is assigned an internal id by the placement in the file. The first edge has id 0, the second id 1, and so on.

About

Alternative route planning tool (for bicycle)

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Cyclops - an alternative route planning tool for bicycles

Cyclops finds alternative routes between two points using multiple metrics. Each of the paths is optimal for some combination of the metrics and sufficiently different from the others according to user preference. Alternative routes from Pforzheim to Stuttgart

It does this fast by using the Dijkstra speed-up technique multicriteria contraction hierarchies.

Cyclops was initially implemented for bicycle routes and three specific metrics. Although the Cyclops back end is capable of handling other metrics and a different number of metrics its front end is only designed for this use case and would need adaption for a different one.

Building

To Build Cyclops first clone it and change into its directory:

git clone --recursive https://github.com/lesstat/cyclops
cd cyclops

Then create a build directory for cmake and run cmake and make.

mkdir build
cd build
cmake ..
make -j

Usage

The main executable of Cyclops is cyclops. It has the following cli options:

$ ./build/cyclops -h
-h [ --help ] prints help message
loading options:
-t [ --text ] arg load graph from text file
-b [ --bin ] arg load graph form binary file
--zi input text file is gzipped
-d [ --dimension ] arg Dimension of loaded Graph
actions:
--save arg save graph to binary file
--test runs normal dijkstra and CH dijktra for comparison
-w [ --web ] start webserver for interaction via browser

It needs exactly one of the first two in the loading category to load a graph and at least one of the second category. --zi can be combined with the -t option to directly read zip compressed graph files in text format. -d sets the dimension of the loaded graph. Default is 3. Dimensions one to three are supported currently. Larger Dimension can be added easily see below.

The actions are executed in the order they are displayed above.

--save prompts the application write the graph to a binary file for faster loading (no text parsing necessary).

--test executes 1,000 random source-target queries with Dijkstra and CH-Dijkstra, assures that they output the same path and prints the speed-up at the end.

--web starts a web server for interactive use. Cyclops expects a directory named web with the contents for the web interface at the current working directory (not the directory the executable is located in). Starting from the root directory of the repository is currently mandatory for the web interface. The Web interface is available at http://localhost:8080/web

Different Number of Metrics

Although Cyclops was initially implemented to handle exactly three metrics, it was adapted to handle an arbitrary number of metrics. For best performance the number of metrics is needed at compile time. If you want to work with more metrics change the switch statement at the bottom of the main function in main.cpp

For four metrics the following lines would need to be added:

case4: {
return run<4>(vm, loadFileName, saveFileName);
break;
}

Graph Data

Cyclops can read road graphs in two different formats. The important one is a text format. The other one is a binary format which Cyclops can write from any valid input graph and read again. It is used for faster reading and writing of graphs which should not be modified any more.

The text format consists of a header and a body.

Header

The header starts with an arbitrary number of lines reserved for comments. These lines start with and #. They are followed by a blank line and afterwards three lines defining the contents of the file:

  • Dimension of the cost vector
  • Number of nodes
  • Number of edges

A header could look like this:

# Creation date: 02.03.2018
# Edge Costs: length, travel time, positive height ascent
3
8456123
17987123

Which means there is a vector of size three assigned to every edge. There are 8,456,123 nodes in the graph and 17,987,123 edges.

As mentioned above Cyclops needs to be compiled with the right dimension for different dimensions to work. This will be checked when the graph is read.

Nodes

Immediately after the header (without a blank line) follows the data for all nodes, one node per line:

0 125799 53.0749415 8.7868047 3.4728513520111997 0

Those values are:

<internal id> <osmid> <latitude> <longitude> <height> <CH-Level>

No two nodes are allowed to have the same internal id. The CH-Level is important for the speeding up the shortest path search. A Ch-Graph can for example be constructed from a normal graph by my multi-ch-constructor.

Cyclops works with a normal graph too, but slowly :-)

Edges

After the last node the edges of the graph start. An edge looks like this:

22 104289 6 0.17316000000255372 1.5 -1 -1

which stands for:

<internal source node id> <internal destinantion node id> <cost 1>
<cost 2> .. <cost dimension> <replaced edge id 1> <replaced edge id 2>

Edges are always one way. The replaced edge ids are for shortcut edges in a CH-Graph. Normal edges don't replace other edges and there for have -1 as replaced edge id. An edge is assigned an internal id by the placement in the file. The first edge has id 0, the second id 1, and so on.

About

Alternative route planning tool (for bicycle)

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Cyclops - an alternative route planning tool for bicycles

Cyclops finds alternative routes between two points using multiple metrics. Each of the paths is optimal for some combination of the metrics and sufficiently different from the others according to user preference. Alternative routes from Pforzheim to Stuttgart

It does this fast by using the Dijkstra speed-up technique multicriteria contraction hierarchies.

Cyclops was initially implemented for bicycle routes and three specific metrics. Although the Cyclops back end is capable of handling other metrics and a different number of metrics its front end is only designed for this use case and would need adaption for a different one.

Building

To Build Cyclops first clone it and change into its directory:

git clone --recursive https://github.com/lesstat/cyclops
cd cyclops

Then create a build directory for cmake and run cmake and make.

mkdir build
cd build
cmake ..
make -j

Usage

The main executable of Cyclops is cyclops. It has the following cli options:

$ ./build/cyclops -h
-h [ --help ] prints help message
loading options:
-t [ --text ] arg load graph from text file
-b [ --bin ] arg load graph form binary file
--zi input text file is gzipped
-d [ --dimension ] arg Dimension of loaded Graph
actions:
--save arg save graph to binary file
--test runs normal dijkstra and CH dijktra for comparison
-w [ --web ] start webserver for interaction via browser

It needs exactly one of the first two in the loading category to load a graph and at least one of the second category. --zi can be combined with the -t option to directly read zip compressed graph files in text format. -d sets the dimension of the loaded graph. Default is 3. Dimensions one to three are supported currently. Larger Dimension can be added easily see below.

The actions are executed in the order they are displayed above.

--save prompts the application write the graph to a binary file for faster loading (no text parsing necessary).

--test executes 1,000 random source-target queries with Dijkstra and CH-Dijkstra, assures that they output the same path and prints the speed-up at the end.

--web starts a web server for interactive use. Cyclops expects a directory named web with the contents for the web interface at the current working directory (not the directory the executable is located in). Starting from the root directory of the repository is currently mandatory for the web interface. The Web interface is available at http://localhost:8080/web

Different Number of Metrics

Although Cyclops was initially implemented to handle exactly three metrics, it was adapted to handle an arbitrary number of metrics. For best performance the number of metrics is needed at compile time. If you want to work with more metrics change the switch statement at the bottom of the main function in main.cpp

For four metrics the following lines would need to be added:

case4: {
return run<4>(vm, loadFileName, saveFileName);
break;
}

Graph Data

Cyclops can read road graphs in two different formats. The important one is a text format. The other one is a binary format which Cyclops can write from any valid input graph and read again. It is used for faster reading and writing of graphs which should not be modified any more.

The text format consists of a header and a body.

Header

The header starts with an arbitrary number of lines reserved for comments. These lines start with and #. They are followed by a blank line and afterwards three lines defining the contents of the file:

  • Dimension of the cost vector
  • Number of nodes
  • Number of edges

A header could look like this:

# Creation date: 02.03.2018
# Edge Costs: length, travel time, positive height ascent
3
8456123
17987123

Which means there is a vector of size three assigned to every edge. There are 8,456,123 nodes in the graph and 17,987,123 edges.

As mentioned above Cyclops needs to be compiled with the right dimension for different dimensions to work. This will be checked when the graph is read.

Nodes

Immediately after the header (without a blank line) follows the data for all nodes, one node per line:

0 125799 53.0749415 8.7868047 3.4728513520111997 0

Those values are:

<internal id> <osmid> <latitude> <longitude> <height> <CH-Level>

No two nodes are allowed to have the same internal id. The CH-Level is important for the speeding up the shortest path search. A Ch-Graph can for example be constructed from a normal graph by my multi-ch-constructor.

Cyclops works with a normal graph too, but slowly :-)

Edges

After the last node the edges of the graph start. An edge looks like this:

22 104289 6 0.17316000000255372 1.5 -1 -1

which stands for:

<internal source node id> <internal destinantion node id> <cost 1>
<cost 2> .. <cost dimension> <replaced edge id 1> <replaced edge id 2>

Edges are always one way. The replaced edge ids are for shortcut edges in a CH-Graph. Normal edges don't replace other edges and there for have -1 as replaced edge id. An edge is assigned an internal id by the placement in the file. The first edge has id 0, the second id 1, and so on.

About

Alternative route planning tool (for bicycle)

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Cyclops - an alternative route planning tool for bicycles

Cyclops finds alternative routes between two points using multiple metrics. Each of the paths is optimal for some combination of the metrics and sufficiently different from the others according to user preference. Alternative routes from Pforzheim to Stuttgart

It does this fast by using the Dijkstra speed-up technique multicriteria contraction hierarchies.

Cyclops was initially implemented for bicycle routes and three specific metrics. Although the Cyclops back end is capable of handling other metrics and a different number of metrics its front end is only designed for this use case and would need adaption for a different one.

Building

To Build Cyclops first clone it and change into its directory:

git clone --recursive https://github.com/lesstat/cyclops
cd cyclops

Then create a build directory for cmake and run cmake and make.

mkdir build
cd build
cmake ..
make -j

Usage

The main executable of Cyclops is cyclops. It has the following cli options:

$ ./build/cyclops -h
-h [ --help ] prints help message
loading options:
-t [ --text ] arg load graph from text file
-b [ --bin ] arg load graph form binary file
--zi input text file is gzipped
-d [ --dimension ] arg Dimension of loaded Graph
actions:
--save arg save graph to binary file
--test runs normal dijkstra and CH dijktra for comparison
-w [ --web ] start webserver for interaction via browser

It needs exactly one of the first two in the loading category to load a graph and at least one of the second category. --zi can be combined with the -t option to directly read zip compressed graph files in text format. -d sets the dimension of the loaded graph. Default is 3. Dimensions one to three are supported currently. Larger Dimension can be added easily see below.

The actions are executed in the order they are displayed above.

--save prompts the application write the graph to a binary file for faster loading (no text parsing necessary).

--test executes 1,000 random source-target queries with Dijkstra and CH-Dijkstra, assures that they output the same path and prints the speed-up at the end.

--web starts a web server for interactive use. Cyclops expects a directory named web with the contents for the web interface at the current working directory (not the directory the executable is located in). Starting from the root directory of the repository is currently mandatory for the web interface. The Web interface is available at http://localhost:8080/web

Different Number of Metrics

Although Cyclops was initially implemented to handle exactly three metrics, it was adapted to handle an arbitrary number of metrics. For best performance the number of metrics is needed at compile time. If you want to work with more metrics change the switch statement at the bottom of the main function in main.cpp

For four metrics the following lines would need to be added:

case4: {
return run<4>(vm, loadFileName, saveFileName);
break;
}

Graph Data

Cyclops can read road graphs in two different formats. The important one is a text format. The other one is a binary format which Cyclops can write from any valid input graph and read again. It is used for faster reading and writing of graphs which should not be modified any more.

The text format consists of a header and a body.

Header

The header starts with an arbitrary number of lines reserved for comments. These lines start with and #. They are followed by a blank line and afterwards three lines defining the contents of the file:

  • Dimension of the cost vector
  • Number of nodes
  • Number of edges

A header could look like this:

# Creation date: 02.03.2018
# Edge Costs: length, travel time, positive height ascent
3
8456123
17987123

Which means there is a vector of size three assigned to every edge. There are 8,456,123 nodes in the graph and 17,987,123 edges.

As mentioned above Cyclops needs to be compiled with the right dimension for different dimensions to work. This will be checked when the graph is read.

Nodes

Immediately after the header (without a blank line) follows the data for all nodes, one node per line:

0 125799 53.0749415 8.7868047 3.4728513520111997 0

Those values are:

<internal id> <osmid> <latitude> <longitude> <height> <CH-Level>

No two nodes are allowed to have the same internal id. The CH-Level is important for the speeding up the shortest path search. A Ch-Graph can for example be constructed from a normal graph by my multi-ch-constructor.

Cyclops works with a normal graph too, but slowly :-)

Edges

After the last node the edges of the graph start. An edge looks like this:

22 104289 6 0.17316000000255372 1.5 -1 -1

which stands for:

<internal source node id> <internal destinantion node id> <cost 1>
<cost 2> .. <cost dimension> <replaced edge id 1> <replaced edge id 2>

Edges are always one way. The replaced edge ids are for shortcut edges in a CH-Graph. Normal edges don't replace other edges and there for have -1 as replaced edge id. An edge is assigned an internal id by the placement in the file. The first edge has id 0, the second id 1, and so on.

About

Alternative route planning tool (for bicycle)

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages