Commit 5e6da241 authored by Jean-Marie Favreau's avatar Jean-Marie Favreau
Browse files

Ajout d'un outil de visualisation d'évaluations (pas fini, il manque la carte, et la navigation)

parent 3b035ace
<!DOCTYPE html>
<html lang="fr-FR" class="no-js">
<head>
<meta charset="UTF-8">
<title>Browser tool</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- bootstrap -->
<link href="node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="node_modules/bootstrap/dist/js/bootstrap.bundle.min.js" ></script>
<!-- bootstrap dark -->
<link rel="stylesheet" href="node_modules/bootstrap-dark/src/bootstrap-dark.css" />
<!-- jquery -->
<script src="node_modules/jquery/dist/jquery.min.js"></script>
<!-- Library Leaflet -->
<link rel="stylesheet" href="node_modules/leaflet/dist/leaflet.css" />
<script src="node_modules/leaflet/dist/leaflet.js"></script>
<script src="js/evaluate-segmentation.js"></script>
<!-- bootstrap table -->
<link href="node_modules/bootstrap-table/dist/bootstrap-table.min.css" rel="stylesheet">
<script src="node_modules/bootstrap-table/dist/bootstrap-table.min.js"></script>
<script>
function is_evaluation_incorrect(ec) {
for(var qid in window.q_json) {
if (ec[qid] != window.q_json[qid]["default"])
return true;
}
return false;
}
function update_buttons() {
var nb_cr = window.crossroads.length;
var nb_cr_eval = 0;
var nb_cr_incorrect = 0;
for(var idc in window.crossroads) {
ec = get_evaluation_crossroad(window.crossroads[idc]);
if (ec != 0) {
nb_cr_eval += 1;
if (is_evaluation_incorrect(ec))
nb_cr_incorrect += 1;
}
}
$("#show-all span").html("(" + nb_cr + ")");
$("#show-evaluated span").html("(" + nb_cr_eval + ")");
$("#show-incorrect span").html("(" + nb_cr_incorrect + ")");
}
function get_evaluation_crossroad(crossroad) {
for (var idc in crossroad) {
if (crossroad[idc]["type"] == "evaluation")
return crossroad[idc];
}
return 0;
}
function build_data_from_crossroads() {
var result = [];
i = 0;
for(var idc in window.crossroads) {
cr_line = {};
eval = get_evaluation_crossroad(window.crossroads[idc]);
fields = Settings.compute_fields(window.crossroads[idc]);
cr_line["evaluated"] = eval != 0;
cr_line["incorrect"] = eval != 0 && is_evaluation_incorrect(eval);
if (window.mode == "all" ||
(cr_line["evaluated"] && window.mode == "evaluated") ||
(cr_line["incorrect"] && window.mode == "incorrect")) {
for(var qid in window.q_json) {
if (eval == 0 || eval[qid] == window.q_json[qid]["default"])
cr_line[qid] = "-";
else
cr_line[qid] = eval[qid];
}
cr_line["id"] = "" + i;
for(var x in window.cf_json) {
cr_line[x] = fields[x];
}
result.push(cr_line);
}
i += 1;
}
return result;
}
function build_array_from_crossroads() {
data = build_data_from_crossroads();
table = $('#table')
table.bootstrapTable('destroy').bootstrapTable({data: data});
}
function display_browser_interface() {
build_array_from_crossroads();
$("#main-container>div").css("display", "none");
$("#browser").css("display", "block");
}
function build_browser_interface() {
// Create columns
html = '<th scope="row" data-field="id">ID</th>';
html += '<th data-field="state" data-checkbox="true"></th>';
window.q_json = JSON.parse(Settings.question_list);
// Columns from questions
for(var qid in window.q_json) {
html += '<th scope="col" data-sortable="true" data-field="' + qid + '">' + window.q_json[qid]["question"] + '</th>';
}
window.cf_json = JSON.parse(Settings.computed_fields);
// Computed columns
for(var x in window.cf_json) {
html += '<th scope="col" data-sortable="true" data-field="' + x + '">' + window.cf_json[x] + '</th>';
}
$("#table_header").html(html);
}
function set_title() {
$("h1").text(title_evaluation_browser_page);
document.title = title_evaluation_browser_page;
}
function set_intro() {
$("#intro").html(intro_evaluation_browser_page);
}
$(document).ready(function () {
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.has('tool')) {
tool = urlParams.get('tool');
}
else {
console.log("cannot identify a tool, select the default one");
tool = "evaluate-segmentation";
}
const script = document.createElement('script');
script.src = 'js/' + tool + '.js';
script.id = 'evaluation-parameters';
document.body.appendChild(script);
script.onerror = function() {
$("#main-container>div").css("display", "none");
$("#error-script").css("display", "block");
}
script.onload = () => {
set_title();
set_intro();
build_browser_interface();
$("#inputFile").on("change", function handleFileSelect(evt) {
if (evt == null || evt.target == null || evt.target.files == null || evt.target.files.length == 0) {
console.log("no input file");
return;
}
var file = evt.target.files[0];
if (file.type != "application/json") {
console.log("bad format");
return;
}
const fr = new FileReader();
fr.addEventListener("load", e => {
$("#main-container>div").css("display", "none");
$("#chargement").css("display", "block");
// load data
window.crossroads = JSON.parse(fr.result);
window.mode = "all";
display_browser_interface();
update_buttons();
});
fr.readAsText(file);
window.input_filename = evt.target.files[0].name;
});
$("#show-all").click(function(evt) {
window.mode = "all";
build_array_from_crossroads();
});
$("#show-evaluated").click(function(evt) {
window.mode = "evaluated";
build_array_from_crossroads();
});
$("#show-incorrect").click(function(evt) {
window.mode = "incorrect";
build_array_from_crossroads();
});
}
});
</script>
<style>
#question, #chargement, #browser, #error-script { display: none; }
#crossroad-rendering { height: 100%; }
</style>
</head>
<body>
<div class="container-xxl" id="main-container">
<h1>Evaluation tool</h1>
<p class="lead" id="intro"></p>
</p>
<div id="start">
<div class="position-absolute top-50 start-50 translate-middle fs-1">
<p>Select a <code>json</code> file</p>
<div class="btn btn-primary btn-block" style="width: 100%">
<label style="padding: 0" tkey="chooseFile">Load crossroads</label>
<input type="file" id="inputFile" name="files[]" accept="application/json" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; cursor: pointer; opacity: 0">
</div>
</div>
</div>
<div id="chargement">
<div class="position-absolute top-50 start-50 translate-middle fs-1">Loading data...</div>
</div>
<div id="browser">
<div class="row">
<div class="col">
<button id="show-all" class="btn btn-primary btn-block form-control" type="button">All crossroads <span></span></button>
</div>
<div class="col">
<button id="show-evaluated" class="btn btn-primary btn-block form-control" type="button">Evaluated crossroads <span></span></button>
</div>
<div class="col">
<button id="show-incorrect" class="btn btn-primary btn-block form-control" type="button">Only incorrect crossroads <span></span></button>
</div>
</div>
<div class="card">
<div class="card-body">
<h2 class="card-title"><span id="crossroad_title"></span></h2>
<div id="crossroad-rendering"></div>
</div>
</div>
<div>
<table class="table-dark"
id="table"
data-filter="true"
data-height="460"
data-single-select="true"
data-click-to-select="true"
data-pagination="true">
<thead>
<tr id="table_header">
</tr>
</thead>
</table>
</div>
</div>
<div id="error-script">
<div class="position-absolute top-50 start-50 translate-middle fs-1">Error while loading tool</div>
</div>
</div>
</body>
</html>
......@@ -2,7 +2,7 @@
<html lang="fr-FR" class="no-js">
<head>
<meta charset="UTF-8">
<title>Crossroad segmentation quality evaluation</title>
<title>Evaluation tool</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- bootstrap -->
......@@ -46,7 +46,7 @@
function build_question_interface() {
questions = '';
window.q_json = JSON.parse(settings_questions);
window.q_json = JSON.parse(Settings.question_list);
qid = 0;
for(var key in window.q_json){
......@@ -152,7 +152,7 @@
}
// right side
render_crossroad(window.crossroads[window.crossroads_index[window.current_id]], "crossroad-rendering", "crossroad_link");
Settings.render_crossroad(window.crossroads[window.crossroads_index[window.current_id]], "crossroad-rendering", "crossroad_link");
}
// get answers from the form and store them in the data structure (that contains the initial json)
......@@ -291,7 +291,14 @@
}
function set_title() {
$("h1").text(Settings.title_evaluation_page);
document.title = Settings.title_evaluation_page;
}
function set_intro() {
$("#intro").html(Settings.intro_evaluation_page);
}
$(document).ready(function () {
......@@ -316,6 +323,9 @@
}
script.onload = () => {
set_title();
set_intro();
$("#next").click(function(evt) {
set_current_crossroad_evaluation();
window.current_id += 1;
......@@ -426,6 +436,8 @@
// load data
window.crossroads = JSON.parse(fr.result);
// TODO: test if the json is a valid crossroad list
// set numbers
$("#nb_crossroads").text(window.crossroads.length);
......@@ -458,8 +470,8 @@
<body>
<div class="container-xxl" id="main-container">
<h1>Crossroad segmentation quality evaluation</h1>
<p class="lead">By answering the following questions, you will evaluate the quality of a junction detection and segmentation algorithm in <a href="https://www.openstreetmap.org/">OpenStreetMap</a>, and participate in the <a href="https://activmap.limos.fr/">ANR ACTIVmap project</a>. This tool is part of the <a href="index.html">main evaluation toolkit</a>.</p>
<h1>Evaluation tool</h1>
<p class="lead" id="intro"></p>
</p>
<div id="start">
<div class="position-absolute top-50 start-50 translate-middle fs-1">
......
......@@ -35,7 +35,7 @@ cd crossroads-segmentation/src
</pre>
</li>
<li>Follow the link for <a href="evaluate.html?tool=evaluate-segmentation">segmentation evaluation</a>, load <code>crossroads-obelisque-1000.json</code> and answer all the questions. Download the updated json file with the evaluation answers.</li>
<li>Use the evaluation browser to have a user friendly rendering of this json file. <em>(available soon)</em></li>
<li>Use the <a href="eval-browser.html?tool=evaluate-segmentation">evaluation browser</a> to have a user friendly rendering of this json file.</li>
</ol>
</div>
......
settings_questions = '{ \
"scale": {"question": "Crossroad scale", "type": "multiple_choice", "values": ["correct", "too large", "too small"], "default": "correct" }, \
"nb_branches": { "question": "Number of branches", "type": "multiple_choice", "values": ["correct", "too few", "too much"], "default": "correct" }, \
"branches": { "question": "Branches configuration", "type": "multiple_choice", "values": ["correct", "two or more branches are merged", "one or more branch is split", "merged and split branches"], "default": "correct" }, \
"edges": {"question": "Edge position", "type": "multiple_choice", "values": ["correct", "too far", "too close"], "default": "correct" }, \
"completness": {"question": "Completness", "type": "multiple_choice", "values": ["correct", "missing parts", "excess parts"], "default": "correct" }, \
"comments": {"question": "Comments", "type": "text", "default": "" } \
}';
Settings = {};
Settings.question_list = '{ \
"scale": {"question": "Crossroad scale", "type": "multiple_choice", "values": ["correct", "too large", "too small"], "default": "correct" }, \
"nb_branches": { "question": "Number of branches", "type": "multiple_choice", "values": ["correct", "too few", "too much"], "default": "correct" }, \
"branches": { "question": "Branches configuration", "type": "multiple_choice", "values": ["correct", "two or more branches are merged", "one or more branch is split", "merged and split branches"], "default": "correct" }, \
"edges": {"question": "Edge position", "type": "multiple_choice", "values": ["correct", "too far", "too close"], "default": "correct" }, \
"completness": {"question": "Completness", "type": "multiple_choice", "values": ["correct", "missing parts", "excess parts"], "default": "correct" }, \
"comments": {"question": "Comments", "type": "text", "default": "" } \
}';
Settings.computed_fields = '{ "complex_node_number": "#complex nodes", "length": "Length" }';
Settings.title_evaluation_page = "Crossroad segmentation quality evaluation";
Settings.intro_evaluation_page = 'By answering the following questions, you will evaluate the quality of a junction detection and segmentation algorithm in <a href="https://www.openstreetmap.org/">OpenStreetMap</a>, and participate in the <a href="https://activmap.limos.fr/">ANR ACTIVmap project</a>. This tool is part of the <a href="index.html">main evaluation toolkit</a>.';
title_evaluation_browser_page = "Crossroad segmentation quality evaluation browser";
intro_evaluation_browser_page = 'Browse the result of a quality evaluation process on a series of junction detection and segmentations algorithm. in <a href="https://www.openstreetmap.org/">OpenStreetMap</a>, and participate in the <a href="https://activmap.limos.fr/">ANR ACTIVmap project</a>. This tool is part of the <a href="index.html">main evaluation toolkit</a>.';
// from jquery.color.js plugin
Colors = {};
Colors.names = {
Settings.Colors = {};
Settings.Colors.names = {
blue: "#0000ff",
lime: "#00ff00",
yellow: "#ffff00",
......@@ -27,11 +37,12 @@ Colors.names = {
violet: "#800080",
silver: "#c0c0c0"
};
// from https://stackoverflow.com/a/10014969/5319942
Colors.list = function(nb) {
Settings.Colors.list = function(nb) {
var result = [];
for (var key in Colors.names) {
result.push(Colors.names[key]);
for (var key in Settings.Colors.names) {
result.push(Settings.Colors.names[key]);
if (result.length == nb)
break;
}
......@@ -39,8 +50,27 @@ Colors.list = function(nb) {
};
Settings.compute_complex_node_number = function(crossroad) {
// TODO
return 1;
}
Settings.compute_crossroad_length = function(crossroad) {
// TODO
return 0.0;
}
Settings.compute_fields = function(crossroad) {
result = {};
result["complex_node_number"] = Settings.compute_complex_node_number(crossroad);
result["length"] = Settings.compute_crossroad_length(crossroad);
return result;
}
function render_crossroad(current_crossroad, divID, crossroadLinksID) {
Settings.render_crossroad = function(current_crossroad, divID, crossroadLinksID) {
// sort using first branches, then crossroad core
current_crossroad.sort((x1, x2) => x1["type"].localeCompare(x2["type"]));
......@@ -82,7 +112,7 @@ function render_crossroad(current_crossroad, divID, crossroadLinksID) {
// build a random list of colors
colors = Colors.list(current_crossroad.length);
colors = Settings.Colors.list(current_crossroad.length);
// for each element of the crossroad create a layer
for(var eid in current_crossroad) {
......
......@@ -5,6 +5,7 @@
"dependencies": {
"bootstrap": "^5.1.3",
"bootstrap-dark": "^1.0.3",
"bootstrap-table": "^1.18.3",
"jquery": "^3.6.0",
"leaflet": "^1.7.1"
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment