Spaces:
Running
Running
tyriaa
commited on
Commit
·
41eaee5
1
Parent(s):
50a5d82
4rd commite
Browse files- static/styles.css +60 -13
- static/sytadin.css +184 -0
- templates/index.html +9 -69
- templates/sytadin.html +168 -0
static/styles.css
CHANGED
@@ -44,15 +44,19 @@ header h1 {
|
|
44 |
display: flex;
|
45 |
gap: 20px;
|
46 |
margin: 20px 0;
|
|
|
47 |
}
|
48 |
|
49 |
/* Section Trafic */
|
50 |
.traffic-info {
|
51 |
flex: 1;
|
|
|
|
|
52 |
background: white;
|
53 |
padding: 20px;
|
54 |
border-radius: 8px;
|
55 |
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
|
56 |
}
|
57 |
|
58 |
.traffic-info h2 {
|
@@ -111,12 +115,25 @@ header h1 {
|
|
111 |
/* Section Carte */
|
112 |
.map-section {
|
113 |
flex: 2;
|
114 |
-
|
115 |
-
|
116 |
-
#map {
|
117 |
-
height: 600px;
|
118 |
border-radius: 8px;
|
119 |
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
}
|
121 |
|
122 |
/* Filtres */
|
@@ -207,18 +224,48 @@ tr.highlighted {
|
|
207 |
}
|
208 |
}
|
209 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
210 |
/* Responsive Design */
|
211 |
@media (max-width: 1024px) {
|
212 |
.traffic-map-container {
|
213 |
flex-direction: column;
|
|
|
214 |
}
|
215 |
-
|
216 |
-
.
|
217 |
-
|
|
|
218 |
}
|
219 |
-
|
220 |
-
|
221 |
-
|
|
|
222 |
}
|
223 |
}
|
224 |
|
@@ -226,15 +273,15 @@ tr.highlighted {
|
|
226 |
.container {
|
227 |
padding: 10px;
|
228 |
}
|
229 |
-
|
230 |
header h1 {
|
231 |
font-size: 1.8em;
|
232 |
}
|
233 |
-
|
234 |
.filter ul {
|
235 |
flex-direction: column;
|
236 |
}
|
237 |
-
|
238 |
.filter li {
|
239 |
width: 100%;
|
240 |
text-align: center;
|
|
|
44 |
display: flex;
|
45 |
gap: 20px;
|
46 |
margin: 20px 0;
|
47 |
+
height: calc(100vh - 250px);
|
48 |
}
|
49 |
|
50 |
/* Section Trafic */
|
51 |
.traffic-info {
|
52 |
flex: 1;
|
53 |
+
min-width: 300px;
|
54 |
+
max-width: 400px;
|
55 |
background: white;
|
56 |
padding: 20px;
|
57 |
border-radius: 8px;
|
58 |
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
59 |
+
overflow-y: auto;
|
60 |
}
|
61 |
|
62 |
.traffic-info h2 {
|
|
|
115 |
/* Section Carte */
|
116 |
.map-section {
|
117 |
flex: 2;
|
118 |
+
background: #d8d8d8; /* Couleur de fond grise de Sytadin */
|
|
|
|
|
|
|
119 |
border-radius: 8px;
|
120 |
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
121 |
+
overflow: hidden;
|
122 |
+
min-width: 0;
|
123 |
+
position: relative;
|
124 |
+
padding: 0;
|
125 |
+
display: flex;
|
126 |
+
align-items: center;
|
127 |
+
justify-content: center;
|
128 |
+
}
|
129 |
+
|
130 |
+
#sytadin-frame {
|
131 |
+
width: 100%;
|
132 |
+
height: 100%;
|
133 |
+
border: none;
|
134 |
+
transform: scale(1.2);
|
135 |
+
margin-top: 350px;
|
136 |
+
transform-origin: center center;
|
137 |
}
|
138 |
|
139 |
/* Filtres */
|
|
|
224 |
}
|
225 |
}
|
226 |
|
227 |
+
/* Styles pour les popups d'incidents */
|
228 |
+
.incident-popup {
|
229 |
+
padding: 10px;
|
230 |
+
max-width: 300px;
|
231 |
+
}
|
232 |
+
|
233 |
+
.incident-description {
|
234 |
+
font-weight: bold;
|
235 |
+
margin-bottom: 8px;
|
236 |
+
color: #E30613;
|
237 |
+
}
|
238 |
+
|
239 |
+
.lanes-info {
|
240 |
+
margin: 5px 0;
|
241 |
+
padding: 5px;
|
242 |
+
background-color: #f8f8f8;
|
243 |
+
border-radius: 4px;
|
244 |
+
}
|
245 |
+
|
246 |
+
.incident-time {
|
247 |
+
font-size: 0.9em;
|
248 |
+
color: #666;
|
249 |
+
margin-top: 8px;
|
250 |
+
border-top: 1px solid #eee;
|
251 |
+
padding-top: 5px;
|
252 |
+
}
|
253 |
+
|
254 |
/* Responsive Design */
|
255 |
@media (max-width: 1024px) {
|
256 |
.traffic-map-container {
|
257 |
flex-direction: column;
|
258 |
+
height: auto;
|
259 |
}
|
260 |
+
|
261 |
+
.traffic-info {
|
262 |
+
max-width: none;
|
263 |
+
width: 100%;
|
264 |
}
|
265 |
+
|
266 |
+
.map-section {
|
267 |
+
width: 100%;
|
268 |
+
height: 600px;
|
269 |
}
|
270 |
}
|
271 |
|
|
|
273 |
.container {
|
274 |
padding: 10px;
|
275 |
}
|
276 |
+
|
277 |
header h1 {
|
278 |
font-size: 1.8em;
|
279 |
}
|
280 |
+
|
281 |
.filter ul {
|
282 |
flex-direction: column;
|
283 |
}
|
284 |
+
|
285 |
.filter li {
|
286 |
width: 100%;
|
287 |
text-align: center;
|
static/sytadin.css
ADDED
@@ -0,0 +1,184 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* Style général */
|
2 |
+
:root {
|
3 |
+
--primary-color: #004494;
|
4 |
+
--secondary-color: #e3051b;
|
5 |
+
--background-color: #f5f5f5;
|
6 |
+
--text-color: #333;
|
7 |
+
--border-color: #ddd;
|
8 |
+
}
|
9 |
+
|
10 |
+
* {
|
11 |
+
margin: 0;
|
12 |
+
padding: 0;
|
13 |
+
box-sizing: border-box;
|
14 |
+
}
|
15 |
+
|
16 |
+
body {
|
17 |
+
font-family: 'Open Sans', sans-serif;
|
18 |
+
background-color: var(--background-color);
|
19 |
+
color: var(--text-color);
|
20 |
+
line-height: 1.6;
|
21 |
+
}
|
22 |
+
|
23 |
+
/* Header */
|
24 |
+
.header {
|
25 |
+
background-color: var(--primary-color);
|
26 |
+
color: white;
|
27 |
+
padding: 1rem;
|
28 |
+
text-align: center;
|
29 |
+
}
|
30 |
+
|
31 |
+
.header h1 {
|
32 |
+
font-size: 1.5rem;
|
33 |
+
margin-bottom: 0.5rem;
|
34 |
+
}
|
35 |
+
|
36 |
+
.header .last-update {
|
37 |
+
font-size: 0.9rem;
|
38 |
+
color: #e0e0e0;
|
39 |
+
}
|
40 |
+
|
41 |
+
/* Container principal */
|
42 |
+
.container {
|
43 |
+
max-width: 1400px;
|
44 |
+
margin: 0 auto;
|
45 |
+
padding: 1rem;
|
46 |
+
display: grid;
|
47 |
+
grid-template-columns: 300px 1fr;
|
48 |
+
gap: 1rem;
|
49 |
+
}
|
50 |
+
|
51 |
+
/* Panneau de gauche */
|
52 |
+
.left-panel {
|
53 |
+
background: white;
|
54 |
+
border-radius: 8px;
|
55 |
+
padding: 1rem;
|
56 |
+
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
57 |
+
}
|
58 |
+
|
59 |
+
.traffic-section {
|
60 |
+
margin-bottom: 2rem;
|
61 |
+
}
|
62 |
+
|
63 |
+
.traffic-section h2 {
|
64 |
+
color: var(--primary-color);
|
65 |
+
font-size: 1.2rem;
|
66 |
+
margin-bottom: 1rem;
|
67 |
+
padding-bottom: 0.5rem;
|
68 |
+
border-bottom: 2px solid var(--primary-color);
|
69 |
+
}
|
70 |
+
|
71 |
+
/* Alertes */
|
72 |
+
.alerts {
|
73 |
+
margin-bottom: 1.5rem;
|
74 |
+
}
|
75 |
+
|
76 |
+
.alert-item {
|
77 |
+
background: #fff8f8;
|
78 |
+
border-left: 4px solid var(--secondary-color);
|
79 |
+
padding: 0.8rem;
|
80 |
+
margin-bottom: 0.8rem;
|
81 |
+
}
|
82 |
+
|
83 |
+
.alert-title {
|
84 |
+
font-weight: 600;
|
85 |
+
color: var(--secondary-color);
|
86 |
+
margin-bottom: 0.3rem;
|
87 |
+
}
|
88 |
+
|
89 |
+
.alert-time {
|
90 |
+
font-size: 0.8rem;
|
91 |
+
color: #666;
|
92 |
+
}
|
93 |
+
|
94 |
+
/* Statistiques de trafic */
|
95 |
+
.traffic-stats {
|
96 |
+
display: grid;
|
97 |
+
grid-template-columns: repeat(2, 1fr);
|
98 |
+
gap: 1rem;
|
99 |
+
margin-bottom: 1.5rem;
|
100 |
+
}
|
101 |
+
|
102 |
+
.stat-box {
|
103 |
+
background: white;
|
104 |
+
border: 1px solid var(--border-color);
|
105 |
+
border-radius: 6px;
|
106 |
+
padding: 1rem;
|
107 |
+
text-align: center;
|
108 |
+
}
|
109 |
+
|
110 |
+
.stat-value {
|
111 |
+
font-size: 1.5rem;
|
112 |
+
font-weight: bold;
|
113 |
+
color: var(--primary-color);
|
114 |
+
}
|
115 |
+
|
116 |
+
.stat-label {
|
117 |
+
font-size: 0.9rem;
|
118 |
+
color: #666;
|
119 |
+
}
|
120 |
+
|
121 |
+
/* Carte */
|
122 |
+
.map-container {
|
123 |
+
background: white;
|
124 |
+
border-radius: 8px;
|
125 |
+
padding: 1rem;
|
126 |
+
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
127 |
+
}
|
128 |
+
|
129 |
+
.map-controls {
|
130 |
+
margin-bottom: 1rem;
|
131 |
+
display: flex;
|
132 |
+
gap: 0.5rem;
|
133 |
+
}
|
134 |
+
|
135 |
+
.map-button {
|
136 |
+
padding: 0.5rem 1rem;
|
137 |
+
border: 1px solid var(--border-color);
|
138 |
+
border-radius: 4px;
|
139 |
+
background: white;
|
140 |
+
cursor: pointer;
|
141 |
+
font-size: 0.9rem;
|
142 |
+
transition: all 0.2s;
|
143 |
+
}
|
144 |
+
|
145 |
+
.map-button:hover {
|
146 |
+
background: #f0f0f0;
|
147 |
+
}
|
148 |
+
|
149 |
+
.map-button.active {
|
150 |
+
background: var(--primary-color);
|
151 |
+
color: white;
|
152 |
+
border-color: var(--primary-color);
|
153 |
+
}
|
154 |
+
|
155 |
+
#map {
|
156 |
+
height: calc(100vh - 200px);
|
157 |
+
border-radius: 8px;
|
158 |
+
overflow: hidden;
|
159 |
+
}
|
160 |
+
|
161 |
+
/* Responsive */
|
162 |
+
@media (max-width: 1024px) {
|
163 |
+
.container {
|
164 |
+
grid-template-columns: 1fr;
|
165 |
+
}
|
166 |
+
|
167 |
+
.left-panel {
|
168 |
+
order: 2;
|
169 |
+
}
|
170 |
+
|
171 |
+
.map-container {
|
172 |
+
order: 1;
|
173 |
+
}
|
174 |
+
|
175 |
+
#map {
|
176 |
+
height: 500px;
|
177 |
+
}
|
178 |
+
}
|
179 |
+
|
180 |
+
@media (max-width: 768px) {
|
181 |
+
.traffic-stats {
|
182 |
+
grid-template-columns: 1fr;
|
183 |
+
}
|
184 |
+
}
|
templates/index.html
CHANGED
@@ -25,6 +25,7 @@
|
|
25 |
<!-- Section Gauche : Trafic -->
|
26 |
<section class="traffic-info">
|
27 |
<h2>État du trafic</h2>
|
|
|
28 |
<div class="traffic-items">
|
29 |
<div class="icon-item">
|
30 |
<div class="transport-icon">
|
@@ -38,12 +39,6 @@
|
|
38 |
</div>
|
39 |
<div class="impacted-lines" data-category="Métro"></div>
|
40 |
</div>
|
41 |
-
<div class="icon-item">
|
42 |
-
<div class="transport-icon">
|
43 |
-
<img src="{{ url_for('static', filename='icons/Bus.svg') }}" alt="Bus" class="icon-img"> Bus
|
44 |
-
</div>
|
45 |
-
<div class="impacted-lines" data-category="Bus"></div>
|
46 |
-
</div>
|
47 |
<div class="icon-item">
|
48 |
<div class="transport-icon">
|
49 |
<img src="{{ url_for('static', filename='icons/Transilien.png') }}" alt="Transilien" class="icon-img"> Transilien
|
@@ -56,12 +51,18 @@
|
|
56 |
</div>
|
57 |
<div class="impacted-lines" data-category="Tram"></div>
|
58 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
59 |
</div>
|
60 |
</section>
|
61 |
|
62 |
<!-- Section Droite : Carte -->
|
63 |
<section class="map-section">
|
64 |
-
<
|
65 |
</section>
|
66 |
</section>
|
67 |
|
@@ -73,9 +74,9 @@
|
|
73 |
<li data-category="all">Tous</li>
|
74 |
<li data-category="RER">RER</li>
|
75 |
<li data-category="Métro">Métro</li>
|
76 |
-
<li data-category="Bus">Bus</li>
|
77 |
<li data-category="Transilien">Transilien</li>
|
78 |
<li data-category="Tram">Tramway</li>
|
|
|
79 |
</ul>
|
80 |
</div>
|
81 |
|
@@ -102,67 +103,6 @@
|
|
102 |
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
|
103 |
<script src="{{ url_for('static', filename='js/traffic.js') }}"></script>
|
104 |
<script>
|
105 |
-
// Initialiser la carte
|
106 |
-
const map = L.map('map').setView([48.8566, 2.3522], 12);
|
107 |
-
|
108 |
-
// Ajouter une couche de tuiles
|
109 |
-
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
110 |
-
attribution: '© Contributeurs OpenStreetMap'
|
111 |
-
}).addTo(map);
|
112 |
-
|
113 |
-
// Récupérer les incidents depuis l'API TomTom
|
114 |
-
fetch('/api/incidents')
|
115 |
-
.then(response => response.json())
|
116 |
-
.then(data => {
|
117 |
-
if (data.status === "success") {
|
118 |
-
const incidents = data.data;
|
119 |
-
|
120 |
-
incidents.forEach(incident => {
|
121 |
-
const coordinates = incident.geometry.coordinates;
|
122 |
-
const type = incident.geometry.type;
|
123 |
-
|
124 |
-
if (type === "LineString") {
|
125 |
-
// Ajouter une polyligne rouge pour les incidents de type LineString
|
126 |
-
const latlngs = coordinates.map(coord => [coord[1], coord[0]]);
|
127 |
-
L.polyline(latlngs, {
|
128 |
-
color: '#E30613',
|
129 |
-
weight: 4,
|
130 |
-
opacity: 0.8
|
131 |
-
}).addTo(map);
|
132 |
-
} else if (type === "Point") {
|
133 |
-
const [lon, lat] = coordinates;
|
134 |
-
const iconCategory = incident.properties.iconCategory;
|
135 |
-
|
136 |
-
const customIcon = L.icon({
|
137 |
-
iconUrl: `/static/icons/${iconCategory}.svg`,
|
138 |
-
iconSize: [72, 72]
|
139 |
-
});
|
140 |
-
|
141 |
-
const categoryDescriptions = {
|
142 |
-
1: "Accident",
|
143 |
-
2: "Brouillard",
|
144 |
-
3: "Conditions dangereuses",
|
145 |
-
4: "Pluie",
|
146 |
-
5: "Verglas",
|
147 |
-
6: "Embouteillage",
|
148 |
-
7: "Voie fermée",
|
149 |
-
8: "Route fermée",
|
150 |
-
9: "Travaux routiers",
|
151 |
-
10: "Vent",
|
152 |
-
11: "Inondation",
|
153 |
-
14: "Véhicule en panne"
|
154 |
-
};
|
155 |
-
|
156 |
-
const description = categoryDescriptions[iconCategory] || "Incident inconnu";
|
157 |
-
|
158 |
-
L.marker([lat, lon], { icon: customIcon })
|
159 |
-
.addTo(map)
|
160 |
-
.bindPopup(`<b>Incident</b><br>${description}`);
|
161 |
-
}
|
162 |
-
});
|
163 |
-
}
|
164 |
-
});
|
165 |
-
|
166 |
// Mettre à jour l'heure de génération
|
167 |
document.getElementById('pageLoadTime').textContent = new Date().toLocaleString('fr-FR', {
|
168 |
hour: '2-digit',
|
|
|
25 |
<!-- Section Gauche : Trafic -->
|
26 |
<section class="traffic-info">
|
27 |
<h2>État du trafic</h2>
|
28 |
+
<p>Sources : RATP - API</p>
|
29 |
<div class="traffic-items">
|
30 |
<div class="icon-item">
|
31 |
<div class="transport-icon">
|
|
|
39 |
</div>
|
40 |
<div class="impacted-lines" data-category="Métro"></div>
|
41 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
<div class="icon-item">
|
43 |
<div class="transport-icon">
|
44 |
<img src="{{ url_for('static', filename='icons/Transilien.png') }}" alt="Transilien" class="icon-img"> Transilien
|
|
|
51 |
</div>
|
52 |
<div class="impacted-lines" data-category="Tram"></div>
|
53 |
</div>
|
54 |
+
<div class="icon-item">
|
55 |
+
<div class="transport-icon">
|
56 |
+
<img src="{{ url_for('static', filename='icons/Bus.svg') }}" alt="Bus" class="icon-img"> Bus
|
57 |
+
</div>
|
58 |
+
<div class="impacted-lines" data-category="Bus"></div>
|
59 |
+
</div>
|
60 |
</div>
|
61 |
</section>
|
62 |
|
63 |
<!-- Section Droite : Carte -->
|
64 |
<section class="map-section">
|
65 |
+
<iframe src="https://www.sytadin.fr/frame/cartographie.jsp.html?largeur=2000&hauteur=1200" frameborder="0" id="sytadin-frame" scrolling="no"></iframe>
|
66 |
</section>
|
67 |
</section>
|
68 |
|
|
|
74 |
<li data-category="all">Tous</li>
|
75 |
<li data-category="RER">RER</li>
|
76 |
<li data-category="Métro">Métro</li>
|
|
|
77 |
<li data-category="Transilien">Transilien</li>
|
78 |
<li data-category="Tram">Tramway</li>
|
79 |
+
<li data-category="Bus">Bus</li>
|
80 |
</ul>
|
81 |
</div>
|
82 |
|
|
|
103 |
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
|
104 |
<script src="{{ url_for('static', filename='js/traffic.js') }}"></script>
|
105 |
<script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
// Mettre à jour l'heure de génération
|
107 |
document.getElementById('pageLoadTime').textContent = new Date().toLocaleString('fr-FR', {
|
108 |
hour: '2-digit',
|
templates/sytadin.html
ADDED
@@ -0,0 +1,168 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="fr">
|
3 |
+
<head>
|
4 |
+
<meta charset="UTF-8">
|
5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6 |
+
<title>Trafic en Île-de-France - Style Sytadin</title>
|
7 |
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
8 |
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
9 |
+
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600;700&display=swap" rel="stylesheet">
|
10 |
+
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css">
|
11 |
+
<link rel="stylesheet" href="{{ url_for('static', filename='sytadin.css') }}">
|
12 |
+
</head>
|
13 |
+
<body>
|
14 |
+
<div class="header">
|
15 |
+
<h1>Trafic en Île-de-France</h1>
|
16 |
+
<div class="last-update">Dernière mise à jour : <span id="pageLoadTime"></span></div>
|
17 |
+
</div>
|
18 |
+
|
19 |
+
<div class="container">
|
20 |
+
<div class="left-panel">
|
21 |
+
<!-- Alertes -->
|
22 |
+
<div class="traffic-section">
|
23 |
+
<h2>Alertes Réseau</h2>
|
24 |
+
<div class="alerts" id="alerts-container">
|
25 |
+
<!-- Les alertes seront injectées ici -->
|
26 |
+
</div>
|
27 |
+
</div>
|
28 |
+
|
29 |
+
<!-- Statistiques -->
|
30 |
+
<div class="traffic-section">
|
31 |
+
<h2>État du trafic</h2>
|
32 |
+
<div class="traffic-stats">
|
33 |
+
<div class="stat-box">
|
34 |
+
<div class="stat-value" id="bouchons-km">-- km</div>
|
35 |
+
<div class="stat-label">de bouchons</div>
|
36 |
+
</div>
|
37 |
+
<div class="stat-box">
|
38 |
+
<div class="stat-value" id="vitesse-moyenne">-- km/h</div>
|
39 |
+
<div class="stat-label">vitesse moyenne</div>
|
40 |
+
</div>
|
41 |
+
</div>
|
42 |
+
</div>
|
43 |
+
|
44 |
+
<!-- Transport en commun -->
|
45 |
+
<div class="traffic-section">
|
46 |
+
<h2>Transport en commun</h2>
|
47 |
+
<div class="traffic-items">
|
48 |
+
<div class="icon-item">
|
49 |
+
<div class="transport-icon">
|
50 |
+
<img src="{{ url_for('static', filename='icons/RER.svg') }}" alt="RER" class="icon-img"> RER
|
51 |
+
</div>
|
52 |
+
<div class="impacted-lines" data-category="RER"></div>
|
53 |
+
</div>
|
54 |
+
<div class="icon-item">
|
55 |
+
<div class="transport-icon">
|
56 |
+
<img src="{{ url_for('static', filename='icons/Metro.png') }}" alt="Métro" class="icon-img"> Métro
|
57 |
+
</div>
|
58 |
+
<div class="impacted-lines" data-category="Métro"></div>
|
59 |
+
</div>
|
60 |
+
<div class="icon-item">
|
61 |
+
<div class="transport-icon">
|
62 |
+
<img src="{{ url_for('static', filename='icons/Bus.svg') }}" alt="Bus" class="icon-img"> Bus
|
63 |
+
</div>
|
64 |
+
<div class="impacted-lines" data-category="Bus"></div>
|
65 |
+
</div>
|
66 |
+
</div>
|
67 |
+
</div>
|
68 |
+
</div>
|
69 |
+
|
70 |
+
<div class="map-container">
|
71 |
+
<div class="map-controls">
|
72 |
+
<button class="map-button active" onclick="switchMapLayer('traffic')">Trafic</button>
|
73 |
+
<button class="map-button" onclick="switchMapLayer('speed')">Vitesses</button>
|
74 |
+
<button class="map-button" onclick="switchMapLayer('incidents')">Incidents</button>
|
75 |
+
</div>
|
76 |
+
<div id="map"></div>
|
77 |
+
</div>
|
78 |
+
</div>
|
79 |
+
|
80 |
+
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
|
81 |
+
<script>
|
82 |
+
// Initialisation de la carte
|
83 |
+
const map = L.map('map').setView([48.8566, 2.3522], 11);
|
84 |
+
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
85 |
+
maxZoom: 19,
|
86 |
+
attribution: '© OpenStreetMap contributors'
|
87 |
+
}).addTo(map);
|
88 |
+
|
89 |
+
// Mise à jour de l'heure
|
90 |
+
function updateLastUpdateTime() {
|
91 |
+
const now = new Date();
|
92 |
+
const options = {
|
93 |
+
hour: '2-digit',
|
94 |
+
minute: '2-digit',
|
95 |
+
day: '2-digit',
|
96 |
+
month: '2-digit',
|
97 |
+
year: '2-digit'
|
98 |
+
};
|
99 |
+
document.getElementById('pageLoadTime').textContent = now.toLocaleString('fr-FR', options);
|
100 |
+
}
|
101 |
+
|
102 |
+
// Fonction pour changer la couche de la carte
|
103 |
+
function switchMapLayer(layer) {
|
104 |
+
// Mettre à jour les boutons
|
105 |
+
document.querySelectorAll('.map-button').forEach(btn => {
|
106 |
+
btn.classList.remove('active');
|
107 |
+
});
|
108 |
+
event.target.classList.add('active');
|
109 |
+
|
110 |
+
// Ici, vous pouvez ajouter la logique pour changer la couche de la carte
|
111 |
+
switch(layer) {
|
112 |
+
case 'traffic':
|
113 |
+
// Afficher la couche de trafic
|
114 |
+
break;
|
115 |
+
case 'speed':
|
116 |
+
// Afficher la couche des vitesses
|
117 |
+
break;
|
118 |
+
case 'incidents':
|
119 |
+
// Afficher la couche des incidents
|
120 |
+
break;
|
121 |
+
}
|
122 |
+
}
|
123 |
+
|
124 |
+
// Fonction pour mettre à jour les alertes
|
125 |
+
function updateAlerts() {
|
126 |
+
fetch('/api/alerts')
|
127 |
+
.then(response => response.json())
|
128 |
+
.then(data => {
|
129 |
+
const container = document.getElementById('alerts-container');
|
130 |
+
container.innerHTML = '';
|
131 |
+
|
132 |
+
data.forEach(alert => {
|
133 |
+
const alertElement = document.createElement('div');
|
134 |
+
alertElement.className = 'alert-item';
|
135 |
+
alertElement.innerHTML = `
|
136 |
+
<div class="alert-title">${alert.title}</div>
|
137 |
+
<div class="alert-time">${alert.time}</div>
|
138 |
+
`;
|
139 |
+
container.appendChild(alertElement);
|
140 |
+
});
|
141 |
+
})
|
142 |
+
.catch(error => console.error('Erreur:', error));
|
143 |
+
}
|
144 |
+
|
145 |
+
// Fonction pour mettre à jour les statistiques
|
146 |
+
function updateStats() {
|
147 |
+
fetch('/api/traffic-stats')
|
148 |
+
.then(response => response.json())
|
149 |
+
.then(data => {
|
150 |
+
document.getElementById('bouchons-km').textContent = data.bouchons_km + ' km';
|
151 |
+
document.getElementById('vitesse-moyenne').textContent = data.vitesse_moyenne + ' km/h';
|
152 |
+
})
|
153 |
+
.catch(error => console.error('Erreur:', error));
|
154 |
+
}
|
155 |
+
|
156 |
+
// Initialisation
|
157 |
+
document.addEventListener('DOMContentLoaded', function() {
|
158 |
+
updateLastUpdateTime();
|
159 |
+
setInterval(updateLastUpdateTime, 60000);
|
160 |
+
|
161 |
+
updateAlerts();
|
162 |
+
updateStats();
|
163 |
+
setInterval(updateAlerts, 300000); // Mise à jour toutes les 5 minutes
|
164 |
+
setInterval(updateStats, 180000); // Mise à jour toutes les 3 minutes
|
165 |
+
});
|
166 |
+
</script>
|
167 |
+
</body>
|
168 |
+
</html>
|