diff --git a/scripts/a.py b/scripts/a.py deleted file mode 100644 index b142953085527fdd947a475a1897721907dd9793..0000000000000000000000000000000000000000 --- a/scripts/a.py +++ /dev/null @@ -1,277 +0,0 @@ -import matplotlib.pyplot as plt -import numpy as np -import networkx as nx -from shapely.geometry import Polygon - -# Points -points = np.array([[2488912.0, 1115153.0], - [2488979.0, 1114141.0], - [2498627.0, 1117834.0], - [2499819.0, 1119645.0], - [2498359.0, 1113540.0], - [2487828.0, 1112948.0], - [2494806.0, 1114873.0], - [2499616.0, 1116520.0], - [2499281.0, 1116589.0], - [2497915.0, 1115857.0], - [2499975.0, 1117114.0], - [2497142.0, 1119572.0], - [2488745.0, 1114763.0], - [2494041.0, 1114769.0], - [2496242.0, 1119699.0], - [2499648.0, 1118428.0], - [2499369.0, 1115509.0], - [2500332.0, 1118330.0], - [2490359.0, 1113416.0], - [2486535.0, 1112032.0], - [2498295.0, 1113913.0], - [2495333.0, 1121462.0], - [2493597.0, 1114661.0], - [2500656.0, 1117699.0], - [2497225.0, 1120644.0], - [2500321.0, 1117673.0], - [2493237.0, 1113488.0], - [2487515.0, 1117697.0], - [2491775.0, 1119342.0], - [2494041.0, 1119836.0], - [2500154.0, 1119824.0], - [2500402.0, 1119186.0], - [2488553.0, 1116943.0], - [2499469.0, 1117097.0], - [2496829.0, 1120305.0], - [2493423.0, 1113262.0], - [2500527.0, 1118645.0], - [2499736.0, 1119816.0], - [2499326.0, 1118992.0], - [2500050.0, 1118238.0], - [2499270.0, 1117680.0], - [2500753.0, 1117527.0], - [2493940.0, 1117414.0], - [2499788.0, 1117456.0], - [2493571.0, 1120018.0], - [2496388.0, 1119533.0], - [2494533.0, 1120651.0], - [2493600.0, 1114365.0], - [2496207.0, 1115659.0], - [2498573.0, 1115793.0], - [2491553.0, 1119000.0], - [2495600.0, 1119250.0], - [2499399.0, 1115714.0], - [2488894.0, 1115135.0], - [2496696.0, 1116410.0], - [2493296.0, 1117149.0], - [2499150.0, 1114693.0], - [2494349.0, 1113299.0], - [2499288.0, 1118655.0], - [2496912.0, 1116287.0], - [2499171.0, 1117949.0], - [2496914.0, 1116506.0], - [2498148.0, 1116295.0], - [2499432.0, 1116312.0], - [2500161.0, 1119935.0], - [2498783.0, 1115972.0], - [2500234.0, 1119555.0], - [2495049.0, 1120436.0], - [2495735.0, 1115435.0], - [2493038.0, 1119778.0], - [2487792.0, 1117521.0], - [2496227.0, 1115259.0], - [2491729.0, 1118587.0], - [2496939.0, 1119488.0], - [2499177.0, 1117785.0], - [2499620.0, 1118736.0], - [2498385.0, 1116858.0], - [2495817.0, 1115035.0], - [2498234.0, 1115355.0], - [2491799.0, 1117508.0], - [2491873.0, 1119074.0], - [2489551.0, 1115765.0], - [2497425.0, 1116548.0], - [2494090.0, 1119794.0], - [2488723.0, 1116564.0], - [2500400.0, 1119982.0], - [2499890.0, 1119190.0], - [2489269.0, 1113883.0], - [2491891.0, 1119053.0], - [2499662.0, 1119484.0], - [2498414.0, 1114352.0], - [2497453.0, 1118044.0], - [2488583.0, 1113987.0], - [2494934.0, 1119901.0], - [2498647.0, 1119026.0], - [2498507.0, 1116671.0], - [2497518.0, 1119428.0], - [2494566.0, 1115021.0], - [2497776.0, 1114515.0], - [2497093.0, 1118740.0], - [2486202.0, 1111405.0], - [2499571.0, 1117311.0], - [2501814.0, 1117463.0], - [2499731.0, 1119167.0], - [2498822.0, 1117871.0], - [2495823.0, 1119383.0], - [2485792.0, 1111318.0], - [2500942.0, 1123625.0], - [2498100.0, 1119190.0], - [2500314.0, 1118144.0], - [2495263.0, 1120814.0], - [2496503.0, 1119828.0], - [2495100.0, 1119282.0], - [2494946.0, 1119906.0], - [2499986.0, 1117599.0], - [2492476.0, 1116165.0], - [2494240.0, 1120766.0], - [2491082.0, 1118374.0], - [2499967.0, 1118415.0], - [2494570.0, 1114688.0], - [2500646.0, 1119188.0], - [2498553.0, 1116033.0], - [2495024.0, 1121099.0], - [2494822.0, 1118597.0], - [2495246.0, 1115119.0], - [2493771.0, 1120441.0], - [2493906.0, 1114511.0], - [2499944.0, 1118161.0], - [2500086.0, 1117464.0], - [2495947.0, 1115729.0], - [2499600.0, 1115100.0], - [2495085.0, 1118827.0], - [2498910.0, 1114429.0], - [2499880.0, 1118772.0], - [2494925.0, 1119605.0], - [2499120.0, 1118319.0], - [2498890.0, 1116913.0], - [2500364.0, 1122923.0], - [2499929.0, 1116547.0], - [2496997.0, 1115960.0], - [2489986.0, 1116227.0], - [2495940.0, 1115536.0], - [2499005.0, 1118858.0], - [2497274.0, 1116681.0], - [2500596.0, 1118825.0], - [2488339.0, 1117110.0], - [2499759.0, 1117746.0], - [2497855.0, 1117041.0], - [2494783.0, 1113645.0], - [2487415.0, 1112733.0], - [2497963.0, 1114745.0], - [2500399.0, 1122132.0], - [2492335.0, 1117556.0], - [2492431.0, 1115892.0], - [2499269.0, 1116272.0], - [2498073.0, 1118482.0], - [2489482.0, 1115448.0], - [2499047.0, 1116116.0], - [2498337.0, 1114795.0], - [2498329.0, 1115591.0], - [2499824.0, 1116792.0], - [2490325.0, 1116210.0], - [2498296.0, 1115061.0], - [2498180.0, 1113981.0], - [2494036.0, 1120612.0], - [2489330.0, 1114571.0], - [2497495.0, 1120801.0], - [2499495.0, 1119268.0], - [2494878.0, 1119801.0], - [2499969.0, 1118468.0], - [2498050.0, 1116973.0], - [2500419.0, 1122878.0], - [2494930.0, 1115148.0], - [2498892.0, 1114497.0], - [2494667.0, 1118537.0], - [2494391.0, 1118402.0], - [2493206.0, 1119928.0], - [2497682.0, 1118619.0], - [2500400.0, 1121878.0], - [2500209.0, 1118791.0], - [2496161.0, 1119516.0], - [2496262.0, 1119732.0], - [2500436.0, 1118490.0], - [2496700.0, 1120102.0], - [2497662.0, 1116048.0], - [2494353.0, 1114581.0], - [2497660.0, 1120989.0], - [2499304.0, 1118142.0], - [2495426.0, 1120280.0], - [2496942.0, 1118901.0], - [2498860.0, 1115065.0], - [2492725.0, 1117213.0], - [2494486.0, 1113431.0], - [2498799.0, 1118272.0], - [2498967.0, 1117437.0], - [2497035.0, 1120556.0], - [2493895.0, 1115452.0], - [2493407.0, 1120097.0], - [2494097.0, 1113193.0], - [2497140.0, 1115813.0], - [2493769.0, 1117287.0], - [2495035.0, 1114952.0], - [2496631.0, 1116130.0], - [2495304.0, 1119106.0], - [2500016.0, 1116765.0], - [2496754.0, 1115732.0], - [2485845.0, 1111438.0], - [2495371.0, 1119303.0], - [2499448.0, 1118286.0], - [2496652.0, 1115539.0], - [2499516.0, 1116077.0], - [2498194.0, 1118825.0], - [2488290.0, 1113598.0], - [2500557.0, 1119591.0], - [2497603.0, 1116321.0], - [2498644.0, 1114766.0], - [2499071.0, 1119132.0], - [2497602.0, 1116765.0], - [2499911.0, 1119669.0], - [2486709.0, 1111980.0], - [2498506.0, 1118344.0], - [2499207.0, 1117324.0], - [2500005.0, 1117858.0], - [2492306.0, 1116676.0], - [2498423.0, 1114149.0], - [2492313.0, 1116330.0], - [2489152.0, 1115064.0], - [2499738.0, 1118100.0], - [2499908.0, 1117575.0]]) - -# Edges (defined by indices of points) -edges = np.array([ - [18, 219], [219, 100], [100, 106], [106, 206], [206, 19], [19, 149], [149, 212], [212, 12], [12, 27], [27, 28], [28, 125], [125, 164], [164, 116], [116, 21], [21, 137], [137, 107], [107, 151], [151, 178], [178, 85], [85, 213], [213, 120], [120, 102], [102, 130], [130, 56], [56, 132], [132, 4], [4, 57], [57, 198], [198, 35], [35, 18] -]) - -# Create a graph from the points and edges -G = nx.Graph() -for i, point in enumerate(points): - G.add_node(i, pos=point) -for edge in edges: - G.add_edge(edge[0], edge[1]) - -# Find all cycles in the graph -cycles = list(nx.cycle_basis(G)) - -# Plotting -plt.figure(figsize=(8, 6)) - -# Plot points -plt.scatter(points[:, 0], points[:, 1], color='red', zorder=5) - -# Plot edges -for edge in edges: - plt.plot(points[edge, 0], points[edge, 1], color='blue') - -# Fill each cycle -for cycle in cycles: - polygon_points = points[cycle] - plt.fill(polygon_points[:, 0], polygon_points[:, 1], alpha=0.3) - -# Add labels to points -for i, (x, y) in enumerate(points): - plt.text(x, y, f' {i}', verticalalignment='bottom', horizontalalignment='right') - -plt.title('Graph with Points and Filled Polygons') -plt.xlabel('X') -plt.ylabel('Y') -plt.autoscale() -plt.grid(True) -#plt.gca().set_aspect('equal', adjustable='box') -plt.show() \ No newline at end of file diff --git a/src/assets/js/app.js b/src/assets/js/app.js index 6684f7b0cb0fb67887d03da92103e1a66a5ec0a3..cbc9422be4e7395eb189c0b36dce6b0040198db5 100644 --- a/src/assets/js/app.js +++ b/src/assets/js/app.js @@ -3,6 +3,7 @@ const legend = document.getElementById("legend"); const chooseOriginPoint = document.getElementById("choose-origin-point"); const originPointCoordElem = document.getElementById('origin-point-coord'); const mapElem = document.getElementById('map'); +const formElem = document.getElementById('form'); let isChoosingOriginPoint = false; let originPointMarker = null; @@ -43,10 +44,50 @@ const getDisplayMode = () => { return 'contour_line'; } - return ''; + // This exception should never be thrown. + throw new Error("Required"); }; +const getCurrentDateTime = () => { + const now = new Date(); + const year = now.getFullYear().toString().padStart(2, '0'); + const month = (now.getMonth() + 1).toString().padStart(2, '0'); + const day = now.getDate().toString().padStart(2, '0'); + const hour = now.getHours().toString().padStart(2, '0'); + const minute = now.getMinutes().toString().padStart(2, '0'); + return year + "-" + month + "-" + day + " " + hour + ":" + minute; +}; + +departureAtInput.value = getCurrentDateTime(); + +formElem.addEventListener('submit', async (e) => { + e.preventDefault(); + + submitButton.disabled = true; + await computeIsochrones(); + submitButton.disabled = false; +}); + +const setMinMaxDepartureAt = async () => { + try { + const response = await fetch('http://localhost:8100/metadata'); + const metadata = await response.json(); + + departureAtInput.min = metadata.start_date + " 00:00"; + departureAtInput.max = metadata.end_date + " 23:59"; + } catch (error) { + alert("Une erreur inconnue s'est produite lors du chargement des métadonnées."); + return; + } +}; +setMinMaxDepartureAt(); + const computeIsochrones = async () => { + if (originPointCoord === null) { + alert("Vous devez d'abord choisir un point d'origine."); + return; + } + clearPreviousIsochroneMap(); const departureDate = departureAtInput.value.split('T')[0]; @@ -65,11 +106,22 @@ const computeIsochrones = async () => { display_mode: displayMode, }; - const response = await fetch('http://localhost:8100/isochrones?' + new URLSearchParams(params).toString()); - const isochrones = await response.json(); + let isochrones; + + try { + const response = await fetch('http://localhost:8100/isochrones?' + new URLSearchParams(params).toString()); + isochrones = await response.json(); + } catch (error) { + alert("Une erreur inconnue s'est produite. Veuillez réessayer."); + return; + } + + if (isochrones.items.length === 0) { + alert("La carte isochrone n'a pas pu être calculée, car aucun arrêt n'est atteignable dans le temps imparti."); + return; + } map.setView([originPointCoord[0], originPointCoord[1]]); - console.log([isochrones.departure_stop_coord.x, isochrones.departure_stop_coord.y]); const palette = [ '#36AB68', // Green 1. @@ -206,10 +258,4 @@ timeLimitInput.addEventListener('change', () => { updateIsochroneIntervalOptions(); }); -submitButton.addEventListener('click', async () => { - submitButton.disabled = true; - await computeIsochrones(); - submitButton.disabled = false; -}); - updateIsochroneIntervalOptions(); diff --git a/src/index.html b/src/index.html index 13a129772dfb18266b6daed1852fd22f0f9ad83a..07ca37c31f923bdd6ceb8c12cf623868e1849ca2 100644 --- a/src/index.html +++ b/src/index.html @@ -27,7 +27,7 @@ <div class="form-container"> <h2>Calculer une carte isochrone</h2> - <form> + <form id="form"> <div class="input-container"> <label>Point d'origine</label> <button class="btn btn-secondary" id="choose-origin-point" type="button"> @@ -38,22 +38,17 @@ <div class="input-container"> <label for="departure-at">Date et heure de départ</label> - <input type="datetime-local" id="departure-at" value="2024-10-09 08:30"> + <input type="datetime-local" id="departure-at" required> </div> <div class="input-container"> <label for="time-limit">Limite de temps (en minutes)</label> - <input type="number" id="time-limit" min="10" max="480" value="60"> + <input type="number" id="time-limit" min="10" max="480" value="60" required> </div> <div class="input-container"> <label for="isochrone-interval">Intervalle entre les isochrones</label> - <select id="isochrone-interval"> - <!-- - <option selected disabled>Sélectionner</option> - <option>15 min.</option> - --> - </select> + <select id="isochrone-interval" required></select> </div> <div class="input-container"> @@ -61,17 +56,17 @@ <div class="display-mode-container"> <label> - <input type="radio" id="display-mode-circles" name="display_mode" checked> Cercles + <input type="radio" id="display-mode-circles" name="display_mode" required checked> Cercles </label> <label> - <input type="radio" id="display-mode-contour-line" name="display_mode"> Ligne de contour + <input type="radio" id="display-mode-contour-line" name="display_mode" required> Ligne de contour </label> </div> </div> <div class="mt-6"> - <button class="btn" id="submit-button" type="button"> + <button class="btn" id="submit-button" type="submit"> <img src="./assets/images/target.png" width="20" height="20"> Calculer </button> </div>