harshdhane commited on
Commit
8b283be
·
verified ·
1 Parent(s): 09ac3f1

Upload 9 files

Browse files
app.py ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, render_template, request, redirect, url_for, session
2
+ import sqlite3
3
+ import os
4
+ from werkzeug.security import generate_password_hash, check_password_hash
5
+
6
+ app = Flask(__name__)
7
+ app.secret_key = 'your_secret_key' # Replace with a secure key
8
+
9
+ # Database setup
10
+ def get_db_connection():
11
+ conn = sqlite3.connect('traffic_management.db')
12
+ conn.row_factory = sqlite3.Row
13
+ return conn
14
+
15
+ # Create database and users table if not exists
16
+ def init_db():
17
+ conn = get_db_connection()
18
+ conn.execute('''
19
+ CREATE TABLE IF NOT EXISTS users (
20
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
21
+ username TEXT UNIQUE NOT NULL,
22
+ password TEXT NOT NULL
23
+ )
24
+ ''')
25
+ conn.commit()
26
+ conn.close()
27
+
28
+ # Initialize database
29
+ init_db()
30
+
31
+ # Upload folder setup
32
+ UPLOAD_FOLDER = 'uploads'
33
+ app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
34
+ if not os.path.exists(UPLOAD_FOLDER):
35
+ os.makedirs(UPLOAD_FOLDER)
36
+
37
+ # Routes
38
+ @app.route('/')
39
+ def index():
40
+ return render_template('index.html')
41
+
42
+ @app.route('/main')
43
+ def main_dashboard():
44
+ if 'username' not in session:
45
+ session['referrer'] = 'main'
46
+ return redirect(url_for('login'))
47
+ return render_template('main.html')
48
+
49
+ @app.route('/login', methods=['GET', 'POST'])
50
+ def login():
51
+ if request.method == 'POST':
52
+ username = request.form['username']
53
+ password = request.form['password']
54
+
55
+ conn = get_db_connection()
56
+ user = conn.execute('SELECT * FROM users WHERE username = ?', (username,)).fetchone()
57
+ conn.close()
58
+
59
+ if user and check_password_hash(user['password'], password):
60
+ session['username'] = user['username']
61
+ redirect_page = session.pop('referrer', 'index')
62
+ return redirect(url_for(redirect_page))
63
+ else:
64
+ return render_template('login.html', error="Invalid username or password.")
65
+ else:
66
+ if 'referrer' not in session and request.referrer and 'login' not in request.referrer and 'signup' not in request.referrer:
67
+ session['referrer'] = request.referrer.split('/')[-1] or 'index'
68
+ return render_template('login.html')
69
+
70
+ @app.route('/signup', methods=['GET', 'POST'])
71
+ def signup():
72
+ if request.method == 'POST':
73
+ username = request.form['username']
74
+ password = request.form['password']
75
+ confirm_password = request.form['confirm_password']
76
+
77
+ if password != confirm_password:
78
+ return "<script>alert('Passwords do not match!'); window.history.back();</script>"
79
+
80
+ hashed_password = generate_password_hash(password)
81
+
82
+ conn = get_db_connection()
83
+ try:
84
+ conn.execute('INSERT INTO users (username, password) VALUES (?, ?)', (username, hashed_password))
85
+ conn.commit()
86
+ return redirect(url_for('login'))
87
+ except sqlite3.IntegrityError:
88
+ return "<script>alert('Username already exists!'); window.history.back();</script>"
89
+ finally:
90
+ conn.close()
91
+ return render_template('signup.html')
92
+
93
+ @app.route('/logout')
94
+ def logout():
95
+ session.clear()
96
+ return redirect(url_for('index'))
97
+
98
+ if __name__ == '__main__':
99
+ app.run(debug=True)
full code.txt ADDED
@@ -0,0 +1,861 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ main.php
2
+
3
+
4
+ <?php session_start(); ?>
5
+ <!DOCTYPE html>
6
+ <html lang="en">
7
+ <head>
8
+ <meta charset="UTF-8">
9
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
10
+ <title>Autonomous Traffic Management System</title>
11
+ <style>
12
+ body {
13
+ font-family: 'Georgia', serif;
14
+ margin: 0;
15
+ padding: 0;
16
+ background-color: #f0f5f9;
17
+ color: #333;
18
+ }
19
+
20
+ header {
21
+ background-color: #1e3a8a;
22
+ color: white;
23
+ padding: 1rem;
24
+ position: relative;
25
+ display: flex;
26
+ align-items: center;
27
+ justify-content: space-between;
28
+ }
29
+
30
+ .logo-title {
31
+ display: flex;
32
+ align-items: center;
33
+ }
34
+
35
+ .logo {
36
+ width: 50px;
37
+ height: 50px;
38
+ margin-right: 15px;
39
+ background-color: #fff;
40
+ border-radius: 50%;
41
+ display: flex;
42
+ align-items: center;
43
+ justify-content: center;
44
+ font-size: 24px;
45
+ font-weight: bold;
46
+ color: #1e3a8a;
47
+ }
48
+
49
+ main {
50
+ padding: 2rem;
51
+ max-width: 1200px;
52
+ margin: 0 auto;
53
+ }
54
+
55
+ .content-container {
56
+ display: flex;
57
+ gap: 2rem;
58
+ }
59
+
60
+ #route-section, #stats-section {
61
+ flex: 1;
62
+ }
63
+
64
+ #map {
65
+ width: 100%;
66
+ height: 400px;
67
+ margin-bottom: 2rem;
68
+ border: 2px solid #ddd;
69
+ border-radius: 8px;
70
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
71
+ }
72
+
73
+ form {
74
+ display: flex;
75
+ flex-direction: column;
76
+ gap: 1rem;
77
+ max-width: 400px;
78
+ background-color: #fff;
79
+ padding: 20px;
80
+ border-radius: 8px;
81
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
82
+ }
83
+
84
+ form label {
85
+ font-weight: bold;
86
+ color: #1e3a8a;
87
+ }
88
+
89
+ form input[type="text"] {
90
+ padding: 10px;
91
+ border: 1px solid #ddd;
92
+ border-radius: 4px;
93
+ font-size: 16px;
94
+ }
95
+
96
+ form button, .nav-btn, .login-btn {
97
+ background-color: #4caf50;
98
+ color: white;
99
+ border: none;
100
+ padding: 10px 15px;
101
+ cursor: pointer;
102
+ font-size: 16px;
103
+ border-radius: 4px;
104
+ transition: background-color 0.3s ease;
105
+ }
106
+
107
+ form button:hover, .nav-btn:hover, .login-btn:hover {
108
+ background-color: #21a271;
109
+ }
110
+
111
+ footer {
112
+ text-align: center;
113
+ padding: 1rem;
114
+ background-color: #1e3a8a;
115
+ color: white;
116
+ bottom: 0;
117
+ width: 100%;
118
+ }
119
+
120
+ h1 {
121
+ margin: 0;
122
+ font-size: 24px;
123
+ }
124
+
125
+ h2 {
126
+ color: #1e3a8a;
127
+ border-bottom: 2px solid #1e3a8a;
128
+ padding-bottom: 10px;
129
+ }
130
+
131
+ .login-btn {
132
+ background-color: #f59e0b;
133
+ }
134
+
135
+ .login-btn:hover {
136
+ background-color: #d97706;
137
+ }
138
+
139
+ .nav-buttons {
140
+ display: flex;
141
+ gap: 10px;
142
+ }
143
+
144
+ .nav-btn {
145
+ background-color: #4caf50;
146
+ color: white;
147
+ border: none;
148
+ padding: 8px 15px;
149
+ margin: 0 5px;
150
+ border-radius: 5px;
151
+ cursor: pointer;
152
+ }
153
+ #route-options button {
154
+ background-color: #e0e7ff;
155
+ color: #1e3a8a;
156
+ border: 1px solid #1e3a8a;
157
+ padding: 10px 15px;
158
+ margin: 5px;
159
+ border-radius: 4px;
160
+ cursor: pointer;
161
+ transition: background-color 0.3s ease;
162
+ }
163
+
164
+ #route-options button:hover {
165
+ background-color: #c7d2fe;
166
+ }
167
+
168
+ #traffic-toggle {
169
+ margin-right: 10px;
170
+ }
171
+
172
+ #traffic-stats-chart {
173
+ max-width: 100%;
174
+ background-color: #fff;
175
+ padding: 20px;
176
+ border-radius: 8px;
177
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
178
+ }
179
+ </style>
180
+ <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
181
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
182
+ <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyA0S_ArVIWsGXkPwpgIhCy2g4y7HlSamX8&libraries=geometry,places&callback=initMap" async defer></script>
183
+ </head>
184
+ <body>
185
+ <header>
186
+ <img src="https://cdn-icons-png.flaticon.com/512/3448/3448339.png" alt="Traffic Management Logo" class="logo">
187
+ <h1>Autonomous Traffic Management Dashboard</h1>
188
+ <div class="nav-buttons">
189
+ <a href="index.php">
190
+ <button class="nav-btn" >Search place</button>
191
+ </a>
192
+ <a href="<?php echo isset($_SESSION['username']) ? 'main.php' : 'login.php'; ?>">
193
+ <button class="nav-btn">Live Traffic & Find Route</button>
194
+ </a>
195
+ </div>
196
+
197
+ <button class="login-btn" onclick="window.location.href='<?php echo isset($_SESSION['username']) ? 'logout.php' : 'login.php'; ?>'">
198
+ <?php echo isset($_SESSION['username']) ? "Hello, " . $_SESSION['username'] : "Hello, Login"; ?>
199
+ </button>
200
+
201
+ </header>
202
+
203
+ <main>
204
+ <div class="content-container">
205
+ <!-- Find Route Section -->
206
+ <section id="route-section">
207
+ <h2>Find Route</h2>
208
+ <form id="route-form">
209
+ <label for="source-input">Source:</label>
210
+ <input id="source-input" type="text" placeholder="Enter source location">
211
+
212
+ <label for="destination-input">Destination:</label>
213
+ <input id="destination-input" type="text" placeholder="Enter destination location">
214
+
215
+ <button type="submit">Find</button>
216
+ </form>
217
+
218
+ <div id="travel-info"></div>
219
+ <div id="route-options" style="margin-top: 20px;"></div>
220
+ </section>
221
+
222
+ <!-- Traffic Stats Section -->
223
+ <section id="stats-section">
224
+ <h2>Traffic Statistics</h2>
225
+ <canvas id="traffic-stats-chart"></canvas>
226
+ </section>
227
+ </div>
228
+
229
+ <!-- Map Section -->
230
+ <section id="map-section">
231
+ <h2>Traffic Visualization</h2>
232
+ <div>
233
+ <label for="traffic-toggle">Show Traffic Layer:</label>
234
+ <input id="traffic-toggle" type="checkbox" checked>
235
+ </div>
236
+ <div id="map" style="height: 400px; width: 100%; margin-top: 10px;"></div>
237
+ </section>
238
+ </main>
239
+
240
+ <footer>
241
+ <p>&copy; Autonomous Traffic Management System Created By @RAVIRAJ kHARADE (RK)</p>
242
+ </footer>
243
+
244
+ <script>
245
+ let map;
246
+ let directionsService;
247
+ let directionsRenderer;
248
+ let trafficLayer;
249
+
250
+ function initMap() {
251
+ map = new google.maps.Map(document.getElementById('map'), {
252
+ center: { lat: 18.4889, lng: 74.0246 },
253
+ zoom: 13
254
+ });
255
+
256
+ trafficLayer = new google.maps.TrafficLayer();
257
+ trafficLayer.setMap(map);
258
+
259
+ directionsService = new google.maps.DirectionsService();
260
+ directionsRenderer = new google.maps.DirectionsRenderer({ map: map });
261
+
262
+ const sourceInput = document.getElementById('source-input');
263
+ const destinationInput = document.getElementById('destination-input');
264
+
265
+ new google.maps.places.Autocomplete(sourceInput);
266
+ new google.maps.places.Autocomplete(destinationInput);
267
+
268
+ // Add event listener to the traffic toggle checkbox
269
+ const trafficToggle = document.getElementById('traffic-toggle');
270
+ trafficToggle.addEventListener('change', () => {
271
+ if (trafficToggle.checked) {
272
+ trafficLayer.setMap(map);
273
+ } else {
274
+ trafficLayer.setMap(null);
275
+ }
276
+ });
277
+ }
278
+
279
+ async function calculateAndDisplayRoute(source, destination) {
280
+ try {
281
+ const response = await directionsService.route({
282
+ origin: source,
283
+ destination: destination,
284
+ travelMode: google.maps.TravelMode.DRIVING,
285
+ provideRouteAlternatives: true
286
+ });
287
+
288
+ directionsRenderer.setDirections(response);
289
+
290
+ const routes = response.routes;
291
+ displayAvailableRoutes(routes);
292
+ } catch (error) {
293
+ alert("Error calculating route: " + error.message);
294
+ }
295
+ }
296
+
297
+ function displayAvailableRoutes(routes) {
298
+ const routeOptionsDiv = document.getElementById('route-options');
299
+ routeOptionsDiv.innerHTML = '<h3>Available Routes:</h3>';
300
+
301
+ routes.forEach((route, index) => {
302
+ const distance = route.legs[0].distance.text;
303
+ const duration = route.legs[0].duration.text;
304
+
305
+ const routeButton = document.createElement('button');
306
+ routeButton.textContent = `Route ${index + 1}: ${distance}, ${duration}`;
307
+ routeButton.addEventListener('click', () => {
308
+ directionsRenderer.setRouteIndex(index);
309
+ checkLiveTrafficOnRoute(route);
310
+ });
311
+
312
+ routeOptionsDiv.appendChild(routeButton);
313
+ });
314
+ }
315
+
316
+ async function checkLiveTrafficOnRoute(route) {
317
+ const trafficDetails = [];
318
+ const path = route.overview_path;
319
+
320
+ for (let i = 0; i < path.length; i += 1) { // Sample every 10th point to reduce API calls
321
+ const point = path[i];
322
+ try {
323
+ const trafficData = await axios.get(`https://maps.googleapis.com/maps/api/distancematrix/json`, {
324
+ params: {
325
+ origins: `${point.lat()},${point.lng()}`,
326
+ destinations: `${point.lat()},${point.lng()}`,
327
+ departure_time: 'now',
328
+ key: 'AIzaSyA0S_ArVIWsGXkPwpgIhCy2g4y7HlSamX8'
329
+ }
330
+ });
331
+
332
+ const durationInTraffic = trafficData.data.rows[0].elements[0].duration_in_traffic;
333
+ if (durationInTraffic) {
334
+ trafficDetails.push({
335
+ lat: point.lat(),
336
+ lng: point.lng(),
337
+ duration: durationInTraffic.text
338
+ });
339
+ } // this above function calculate the duration ising live traffic deatails using coradenates like point.lat() & Point.lng()
340
+ } catch (error) {
341
+ console.error("Error fetching traffic data: ", error);
342
+ }
343
+ }
344
+
345
+ if (trafficDetails.length > 0) {
346
+ displayTrafficAlert(trafficDetails);
347
+ } else {
348
+ alert("This route has no significant traffic. You can proceed.");
349
+ }
350
+ }
351
+
352
+ function displayTrafficAlert(trafficDetails) {
353
+ let message = "Heavy Traffic Detected:\n\n";
354
+
355
+ trafficDetails.forEach((detail, index) => {
356
+ message += `Traffic Point ${index + 1}: Latitude: ${detail.lat}, Longitude: ${detail.lng}, Duration in Traffic: ${detail.duration}\n`;
357
+ });
358
+
359
+ message += "\nThis route has heavy traffic. Consider choosing another route.";
360
+ alert(message);
361
+ }
362
+
363
+ document.getElementById('route-form').addEventListener('submit', (e) => {
364
+ e.preventDefault();
365
+ const sourceLocation = document.getElementById('source-input').value;
366
+ const destinationLocation = document.getElementById('destination-input').value;
367
+
368
+ calculateAndDisplayRoute(sourceLocation, destinationLocation);
369
+ });
370
+
371
+ const ctx = document.getElementById('traffic-stats-chart').getContext('2d');
372
+ new Chart(ctx, {
373
+ type: 'bar',
374
+ data: {
375
+ labels: ['Intersection 1', 'Intersection 2', 'Intersection 3'],
376
+ datasets: [{
377
+ label: 'Traffic Density',
378
+ data: [30, 45, 60],
379
+ backgroundColor: ['green', 'yellow', 'red']
380
+ }]
381
+ },
382
+ options: {
383
+ responsive: true,
384
+ plugins: {
385
+ legend: {
386
+ display: true,
387
+ position: 'top',
388
+ },
389
+ tooltip: {
390
+ enabled: true,
391
+ }
392
+ },
393
+ scales: {
394
+ x: {
395
+ title: {
396
+ display: true,
397
+ text: 'Intersections',
398
+ }
399
+ },
400
+ y: {
401
+ title: {
402
+ display: true,
403
+ text: 'Traffic Density',
404
+ },
405
+ min: 0,
406
+ max: 100
407
+ }
408
+ }
409
+ }
410
+ });
411
+ </script>
412
+ </body>
413
+ </html>
414
+
415
+
416
+
417
+ signup.php
418
+
419
+ <?php
420
+ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
421
+ include 'db.php';
422
+
423
+ $username = $_POST['username'];
424
+ $password = $_POST['password'];
425
+ $confirm_password = $_POST['confirm_password'];
426
+
427
+ if ($password !== $confirm_password) {
428
+ echo "<script>alert('Passwords do not match!'); window.history.back();</script>";
429
+ exit;
430
+ }
431
+
432
+ $hashed_password = password_hash($password, PASSWORD_BCRYPT);
433
+
434
+ $sql = "INSERT INTO users (username, password) VALUES ('$username', '$hashed_password')";
435
+ if ($conn->query($sql) === TRUE) {
436
+ header('Location: login.php');
437
+ } else {
438
+ echo "Error: " . $conn->error;
439
+ }
440
+ }
441
+ ?>
442
+
443
+ <!DOCTYPE html>
444
+ <html lang="en">
445
+ <head>
446
+ <meta charset="UTF-8">
447
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
448
+ <title>Signup</title>
449
+ <style>
450
+ body {
451
+ font-family: 'Arial', sans-serif;
452
+ margin: 0;
453
+ padding: 0;
454
+ background: linear-gradient(135deg, #1d3557, #457b9d);
455
+ display: flex;
456
+ justify-content: center;
457
+ align-items: center;
458
+ height: 100vh;
459
+ color: #333;
460
+ }
461
+ .container {
462
+ background: #fff;
463
+ padding: 2rem;
464
+ border-radius: 10px;
465
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
466
+ width: 350px;
467
+ text-align: center;
468
+ }
469
+ h2 {
470
+ color: #1d3557;
471
+ margin-bottom: 1.5rem;
472
+ }
473
+ .form input {
474
+ width: 100%;
475
+ padding: 12px;
476
+ margin: 10px 0;
477
+ border: 1px solid #ccc;
478
+ border-radius: 5px;
479
+ font-size: 1rem;
480
+ transition: border-color 0.3s ease;
481
+ box-sizing: border-box;
482
+ }
483
+ .form input:focus {
484
+ outline: none;
485
+ border-color: #457b9d;
486
+ }
487
+ .form button {
488
+ width: 100%;
489
+ padding: 12px;
490
+ margin: 15px 0;
491
+ background: #1d3557;
492
+ color: #fff;
493
+ border: none;
494
+ border-radius: 5px;
495
+ cursor: pointer;
496
+ font-size: 1rem;
497
+ transition: background-color 0.3s ease;
498
+ }
499
+ .form button:hover {
500
+ background: #457b9d;
501
+ }
502
+ .form a {
503
+ display: block;
504
+ color: #1d3557;
505
+ text-decoration: none;
506
+ margin-top: 15px;
507
+ font-size: 0.9rem;
508
+ transition: color 0.3s ease;
509
+ }
510
+ .form a:hover {
511
+ color: #457b9d;
512
+ }
513
+ </style>
514
+ </head>
515
+ <body>
516
+ <div class="container">
517
+ <h2>Signup</h2>
518
+ <form class="form" method="POST" action="">
519
+ <input type="text" name="username" placeholder="Username" required>
520
+ <input type="password" name="password" placeholder="Password" required>
521
+ <input type="password" name="confirm_password" placeholder="Confirm Password" required>
522
+ <button type="submit">Signup</button>
523
+ <a href="login.php">Already have an account? Login</a>
524
+ </form>
525
+ </div>
526
+ </body>
527
+ </html>
528
+
529
+
530
+
531
+ db.php
532
+
533
+ <?php
534
+ $servername = "localhost";
535
+ $username = "root";
536
+ $password = "";
537
+ $database = "traffic_management";
538
+
539
+ $conn = new mysqli($servername, $username, $password, $database);
540
+
541
+ if ($conn->connect_error) {
542
+ die("Connection failed: " . $conn->connect_error);
543
+ }
544
+ ?>
545
+
546
+
547
+
548
+ index.php
549
+
550
+ <?php session_start(); ?>
551
+ <!DOCTYPE html>
552
+ <html lang="en">
553
+ <head>
554
+ <meta charset="UTF-8">
555
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
556
+ <title>Autonomous Traffic Management Dashboard</title>
557
+ <style>
558
+ body {
559
+ font-family: 'Georgia', serif;
560
+ margin: 0;
561
+ padding: 0;
562
+ background-color: #f0f5f9;
563
+ color: #333;
564
+ }
565
+ form button, .nav-btn, .login-btn {
566
+ background-color: #4caf50;
567
+ color: white;
568
+ border: none;
569
+ padding: 10px 15px;
570
+ cursor: pointer;
571
+ font-size: 16px;
572
+ border-radius: 4px;
573
+ transition: background-color 0.3s ease;
574
+ }
575
+ form button:hover, .nav-btn:hover, .login-btn:hover {
576
+ background-color: #45a049;
577
+ }
578
+ header {
579
+ background-color: #1e3a8a;
580
+ color: white;
581
+ padding: 1rem;
582
+ position: relative;
583
+ display: flex;
584
+ align-items: center;
585
+ justify-content: space-between;
586
+ }
587
+ footer {
588
+ text-align: center;
589
+ padding: 1rem;
590
+ background-color: #1e3a8a;
591
+ color: white;
592
+ bottom: 0;
593
+ width: 100%;
594
+ }
595
+ .logo-title {
596
+ display: flex;
597
+ align-items: center;
598
+ }
599
+ .logo {
600
+ width: 50px;
601
+ height: 50px;
602
+ margin-right: 15px;
603
+ background-color: #fff;
604
+ border-radius: 50%;
605
+ display: flex;
606
+ align-items: center;
607
+ justify-content: center;
608
+ font-size: 24px;
609
+ font-weight: bold;
610
+ color: #1e3a8a;
611
+ }
612
+ main {
613
+ padding: 2rem;
614
+ max-width: 1200px;
615
+ margin: 0 auto;
616
+ }
617
+ h1 {
618
+ margin: 0;
619
+ font-size: 24px;
620
+ }
621
+ h2 {
622
+ color: #1e3a8a;
623
+ border-bottom: 2px solid #1e3a8a;
624
+ padding-bottom: 10px;
625
+ }
626
+ .login-btn {
627
+ background-color: #f59e0b;
628
+ }
629
+ .login-btn:hover {
630
+ background-color: #d97706;
631
+ }
632
+ .nav-buttons {
633
+ display: flex;
634
+ gap: 10px;
635
+ }
636
+ .nav-btn {
637
+ background-color: #4caf50;
638
+ color: white;
639
+ border: none;
640
+ padding: 8px 15px;
641
+ margin: 0 5px;
642
+ border-radius: 5px;
643
+ cursor: pointer;
644
+ }
645
+ #map {
646
+ height: 550px;
647
+ width: 100%;
648
+ margin-top: 20px;
649
+ }
650
+ #pac-input {
651
+ width: 300px;
652
+ padding: 10px;
653
+ font-size: 16px;
654
+ margin: 20px auto;
655
+ display: block;
656
+ border: 1px solid #bdc3c7;
657
+ border-radius: 5px;
658
+ }
659
+ </style>
660
+ </head>
661
+ <body>
662
+ <header>
663
+ <img src="https://cdn-icons-png.flaticon.com/512/3448/3448339.png" alt="Traffic Management Logo" class="logo">
664
+ <h1>Autonomous Traffic Management Dashboard</h1>
665
+ <div class="nav-buttons">
666
+ <a href="index.php">
667
+ <button class="nav-btn">Search place</button>
668
+ </a>
669
+ <a href="<?php echo isset($_SESSION['username']) ? 'main.php' : 'login.php'; ?>">
670
+ <button class="nav-btn">Live Traffic & Find Route</button>
671
+ </a>
672
+ </div>
673
+ <button class="login-btn" onclick="window.location.href='<?php echo isset($_SESSION['username']) ? 'logout.php' : 'login.php'; ?>'">
674
+ <?php echo isset($_SESSION['username']) ? "Hello, " . $_SESSION['username'] : "Hello, Login"; ?>
675
+ </button>
676
+ </header>
677
+
678
+ <input id="pac-input" type="text" placeholder="Search for a place">
679
+ <div id="map"></div>
680
+
681
+ <script async defer
682
+ src="https://maps.googleapis.com/maps/api/js?key=AIzaSyA0S_ArVIWsGXkPwpgIhCy2g4y7HlSamX8&libraries=geometry,places&callback=initMap">
683
+ </script>
684
+
685
+ <script>
686
+ let map;
687
+ let autocomplete;
688
+
689
+ function initMap() {
690
+ map = new google.maps.Map(document.getElementById('map'), {
691
+ center: { lat: 18.4889, lng: 74.0246 },
692
+ zoom: 13
693
+ });
694
+
695
+ const input = document.getElementById('pac-input');
696
+
697
+ autocomplete = new google.maps.places.Autocomplete(input);
698
+ autocomplete.bindTo('bounds', map);
699
+
700
+ autocomplete.addListener('place_changed', () => {
701
+ const place = autocomplete.getPlace();
702
+ if (!place.geometry) {
703
+ console.log("No details available for the input: '" + place.name + "'");
704
+ return;
705
+ }
706
+
707
+ if (place.geometry.viewport) {
708
+ map.fitBounds(place.geometry.viewport);
709
+ } else {
710
+ map.setCenter(place.geometry.location);
711
+ map.setZoom(17);
712
+ }
713
+
714
+ new google.maps.Marker({
715
+ position: place.geometry.location,
716
+ map: map
717
+ });
718
+ });
719
+ }
720
+ </script>
721
+ </body>
722
+ </html>
723
+
724
+
725
+
726
+ login.php
727
+
728
+ <?php
729
+ session_start();
730
+
731
+ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
732
+ include 'db.php';
733
+
734
+ $username = $_POST['username'];
735
+ $password = $_POST['password'];
736
+
737
+ $sql = "SELECT * FROM users WHERE username = '$username'";
738
+ $result = $conn->query($sql);
739
+
740
+ if ($result->num_rows > 0) {
741
+ $row = $result->fetch_assoc();
742
+ if (password_verify($password, $row['password'])) {
743
+ $_SESSION['username'] = $row['username'];
744
+ $redirectPage = $_SESSION['referrer'] ?? 'index.php';
745
+ unset($_SESSION['referrer']);
746
+ header("Location: $redirectPage");
747
+ exit();
748
+ } else {
749
+ $error = "Invalid username or password.";
750
+ }
751
+ } else {
752
+ $error = "Invalid username or password.";
753
+ }
754
+ }
755
+
756
+ if (!isset($_SESSION['referrer']) && !str_contains($_SERVER['PHP_SELF'], 'login.php') && !str_contains($_SERVER['PHP_SELF'], 'signup.php')) {
757
+ $_SESSION['referrer'] = $_SERVER['HTTP_REFERER'] ?? 'index.php';
758
+ }
759
+ ?>
760
+
761
+ <!DOCTYPE html>
762
+ <html lang="en">
763
+ <head>
764
+ <meta charset="UTF-8">
765
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
766
+ <title>Login</title>
767
+ <style>
768
+ body {
769
+ font-family: 'Arial', sans-serif;
770
+ margin: 0;
771
+ padding: 0;
772
+ background: linear-gradient(135deg, #1d3557, #457b9d);
773
+ display: flex;
774
+ justify-content: center;
775
+ align-items: center;
776
+ height: 100vh;
777
+ color: #333;
778
+ }
779
+ .container {
780
+ background: #fff;
781
+ padding: 2rem;
782
+ border-radius: 10px;
783
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
784
+ width: 350px;
785
+ text-align: center;
786
+ }
787
+ h2 {
788
+ color: #1d3557;
789
+ margin-bottom: 1.5rem;
790
+ }
791
+ .form input {
792
+ width: 100%;
793
+ padding: 10px;
794
+ margin: 10px 0;
795
+ border: 1px solid #ccc;
796
+ border-radius: 5px;
797
+ font-size: 1rem;
798
+ transition: border-color 0.3s ease;
799
+ }
800
+ .form input:focus {
801
+ outline: none;
802
+ border-color: #457b9d;
803
+ }
804
+ .form button {
805
+ width: 100%;
806
+ padding: 12px;
807
+ margin: 15px 0;
808
+ background: #1d3557;
809
+ color: #fff;
810
+ border: none;
811
+ border-radius: 5px;
812
+ cursor: pointer;
813
+ font-size: 1rem;
814
+ transition: background-color 0.3s ease;
815
+ }
816
+ .form button:hover {
817
+ background: #457b9d;
818
+ }
819
+ .form a {
820
+ display: block;
821
+ color: #1d3557;
822
+ text-decoration: none;
823
+ margin-top: 15px;
824
+ font-size: 0.9rem;
825
+ transition: color 0.3s ease;
826
+ }
827
+ .form a:hover {
828
+ color: #457b9d;
829
+ }
830
+ .error {
831
+ color: #e63946;
832
+ margin-top: 10px;
833
+ font-size: 0.9rem;
834
+ }
835
+ </style>
836
+ </head>
837
+ <body>
838
+ <div class="container">
839
+ <h2>Login</h2>
840
+ <form class="form" method="POST" action="">
841
+ <input type="text" name="username" placeholder="Username" required>
842
+ <input type="password" name="password" placeholder="Password" required>
843
+ <button type="submit">Login</button>
844
+ <a href="signup.php">Don't have an account? Sign up</a>
845
+ </form>
846
+ <?php if (isset($error)) echo "<p class='error'>$error</p>"; ?>
847
+ </div>
848
+ </body>
849
+ </html>
850
+
851
+
852
+
853
+ logout.php
854
+
855
+ <?php
856
+ session_start();
857
+ session_destroy();
858
+ header('Location: index.php');
859
+ exit();
860
+
861
+ ?>
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ Flask==2.3.2
2
+ bcrypt==4.0.1
static/css/style.css ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body {
2
+ font-family: 'Georgia', serif;
3
+ margin: 0;
4
+ padding: 0;
5
+ background-color: #f0f5f9;
6
+ color: #333;
7
+ }
8
+
9
+ header {
10
+ background-color: #1e3a8a;
11
+ color: white;
12
+ padding: 1rem;
13
+ position: relative;
14
+ display: flex;
15
+ align-items: center;
16
+ justify-content: space-between;
17
+ }
18
+
19
+ .logo {
20
+ width: 50px;
21
+ height: 50px;
22
+ margin-right: 15px;
23
+ background-color: #fff;
24
+ border-radius: 50%;
25
+ display: flex;
26
+ align-items: center;
27
+ justify-content: center;
28
+ font-size: 24px;
29
+ font-weight: bold;
30
+ color: #1e3a8a;
31
+ }
32
+
33
+ main {
34
+ padding: 2rem;
35
+ max-width: 1200px;
36
+ margin: 0 auto;
37
+ }
38
+
39
+ .content-container {
40
+ display: flex;
41
+ gap: 2rem;
42
+ }
43
+
44
+ #route-section, #stats-section {
45
+ flex: 1;
46
+ }
47
+
48
+ #map {
49
+ width: 100%;
50
+ height: 400px;
51
+ margin-bottom: 2rem;
52
+ border: 2px solid #ddd;
53
+ border-radius: 8px;
54
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
55
+ }
56
+
57
+ form {
58
+ display: flex;
59
+ flex-direction: column;
60
+ gap: 1rem;
61
+ max-width: 400px;
62
+ background-color: #fff;
63
+ padding: 20px;
64
+ border-radius: 8px;
65
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
66
+ }
67
+
68
+ form label {
69
+ font-weight: bold;
70
+ color: #1e3a8a;
71
+ }
72
+
73
+ form input[type="text"] {
74
+ padding: 10px;
75
+ border: 1px solid #ddd;
76
+ border-radius: 4px;
77
+ font-size: 16px;
78
+ }
79
+
80
+ form button, .nav-btn, .login-btn {
81
+ background-color: #4caf50;
82
+ color: white;
83
+ border: none;
84
+ padding: 10px 15px;
85
+ cursor: pointer;
86
+ font-size: 16px;
87
+ border-radius: 4px;
88
+ transition: background-color 0.3s ease;
89
+ }
90
+
91
+ form button:hover, .nav-btn:hover, .login-btn:hover {
92
+ background-color: #45a049;
93
+ }
94
+
95
+ footer {
96
+ text-align: center;
97
+ padding: 1rem;
98
+ background-color: #1e3a8a;
99
+ color: white;
100
+ bottom: 0;
101
+ width: 100%;
102
+ }
103
+
104
+ h1 {
105
+ margin: 0;
106
+ font-size: 24px;
107
+ }
108
+
109
+ h2 {
110
+ color: #1e3a8a;
111
+ border-bottom: 2px solid #1e3a8a;
112
+ padding-bottom: 10px;
113
+ }
114
+
115
+ .login-btn {
116
+ background-color: #f59e0b;
117
+ }
118
+
119
+ .login-btn:hover {
120
+ background-color: #d97706;
121
+ }
122
+
123
+ .nav-buttons {
124
+ display: flex;
125
+ gap: 10px;
126
+ }
127
+
128
+ .nav-btn {
129
+ background-color: #4caf50;
130
+ color: white;
131
+ border: none;
132
+ padding: 8px 15px;
133
+ margin: 0 5px;
134
+ border-radius: 5px;
135
+ cursor: pointer;
136
+ }
137
+
138
+ #route-options button {
139
+ background-color: #e0e7ff;
140
+ color: #1e3a8a;
141
+ border: 1px solid #1e3a8a;
142
+ padding: 10px 15px;
143
+ margin: 5px;
144
+ border-radius: 4px;
145
+ cursor: pointer;
146
+ transition: background-color 0.3s ease;
147
+ }
148
+
149
+ #route-options button:hover {
150
+ background-color: #c7d2fe;
151
+ }
152
+
153
+ #traffic-toggle {
154
+ margin-right: 10px;
155
+ }
156
+
157
+ #traffic-stats-chart {
158
+ max-width: 100%;
159
+ background-color: #fff;
160
+ padding: 20px;
161
+ border-radius: 8px;
162
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
163
+ }
164
+
165
+ .container {
166
+ background: #fff;
167
+ padding: 2rem;
168
+ border-radius: 10px;
169
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
170
+ width: 350px;
171
+ text-align: center;
172
+ }
173
+
174
+ .form input {
175
+ width: 100%;
176
+ padding: 12px;
177
+ margin: 10px 0;
178
+ border: 1px solid #ccc;
179
+ border-radius: 5px;
180
+ font-size: 1rem;
181
+ transition: border-color 0.3s ease;
182
+ box-sizing: border-box;
183
+ }
184
+
185
+ .form input:focus {
186
+ outline: none;
187
+ border-color: #457b9d;
188
+ }
189
+
190
+ .form button {
191
+ width: 100%;
192
+ padding: 12px;
193
+ margin: 15px 0;
194
+ background: #1d3557;
195
+ color: #fff;
196
+ border: none;
197
+ border-radius: 5px;
198
+ cursor: pointer;
199
+ font-size: 1rem;
200
+ transition: background-color 0.3s ease;
201
+ }
202
+
203
+ .form button:hover {
204
+ background: #457b9d;
205
+ }
206
+
207
+ .form a {
208
+ display: block;
209
+ color: #1d3557;
210
+ text-decoration: none;
211
+ margin-top: 15px;
212
+ font-size: 0.9rem;
213
+ transition: color 0.3s ease;
214
+ }
215
+
216
+ .form a:hover {
217
+ color: #457b9d;
218
+ }
219
+
220
+ .error {
221
+ color: #e63946;
222
+ margin-top: 10px;
223
+ font-size: 0.9rem;
224
+ }
225
+
226
+ #pac-input {
227
+ width: 300px;
228
+ padding: 10px;
229
+ font-size: 16px;
230
+ margin: 20px auto;
231
+ display: block;
232
+ border: 1px solid #bdc3c7;
233
+ border-radius: 5px;
234
+ }
templates/index.html ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Autonomous Traffic Management Dashboard</title>
7
+ <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
8
+ </head>
9
+ <body>
10
+ <header>
11
+ <img src="https://cdn-icons-png.flaticon.com/512/3448/3448339.png" alt="Traffic Management Logo" class="logo">
12
+ <h1>Autonomous Traffic Management Dashboard</h1>
13
+ <div class="nav-buttons">
14
+ <a href="{{ url_for('index') }}">
15
+ <button class="nav-btn">Search place</button>
16
+ </a>
17
+ <a href="{{ url_for('main_dashboard') if 'username' in session else url_for('login') }}">
18
+ <button class="nav-btn">Live Traffic & Find Route</button>
19
+ </a>
20
+ </div>
21
+ <button class="login-btn" onclick="window.location.href='{{ url_for('logout') if 'username' in session else url_for('login') }}'">
22
+ {{ "Hello, " + session['username'] if 'username' in session else "Hello, Login" }}
23
+ </button>
24
+ </header>
25
+
26
+ <input id="pac-input" type="text" placeholder="Search for a place">
27
+ <div id="map"></div>
28
+
29
+ <script async defer
30
+ src="https://maps.googleapis.com/maps/api/js?key=AIzaSyA0S_ArVIWsGXkPwpgIhCy2g4y7HlSamX8&libraries=geometry,places&callback=initMap">
31
+ </script>
32
+
33
+ <script>
34
+ let map;
35
+ let autocomplete;
36
+
37
+ function initMap() {
38
+ map = new google.maps.Map(document.getElementById('map'), {
39
+ center: { lat: 18.4889, lng: 74.0246 },
40
+ zoom: 13
41
+ });
42
+
43
+ const input = document.getElementById('pac-input');
44
+
45
+ autocomplete = new google.maps.places.Autocomplete(input);
46
+ autocomplete.bindTo('bounds', map);
47
+
48
+ autocomplete.addListener('place_changed', () => {
49
+ const place = autocomplete.getPlace();
50
+ if (!place.geometry) {
51
+ console.log("No details available for the input: '" + place.name + "'");
52
+ return;
53
+ }
54
+
55
+ if (place.geometry.viewport) {
56
+ map.fitBounds(place.geometry.viewport);
57
+ } else {
58
+ map.setCenter(place.geometry.location);
59
+ map.setZoom(17);
60
+ }
61
+
62
+ new google.maps.Marker({
63
+ position: place.geometry.location,
64
+ map: map
65
+ });
66
+ });
67
+ }
68
+ </script>
69
+ </body>
70
+ </html>
templates/login.html ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Login</title>
7
+ <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
8
+ </head> <style>
9
+ body {
10
+ font-family: 'Arial', sans-serif;
11
+ margin: 0;
12
+ padding: 0;
13
+ background: linear-gradient(135deg, #1d3557, #457b9d);
14
+ display: flex;
15
+ justify-content: center;
16
+ align-items: center;
17
+ height: 100vh;
18
+ color: #333;
19
+ }
20
+ .container {
21
+ background: #fff;
22
+ padding: 2rem;
23
+ border-radius: 10px;
24
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
25
+ width: 350px;
26
+ text-align: center;
27
+ }
28
+ h2 {
29
+ color: #1d3557;
30
+ margin-bottom: 1.5rem;
31
+ }
32
+ .form input {
33
+ width: 100%;
34
+ padding: 10px;
35
+ margin: 10px 0;
36
+ border: 1px solid #ccc;
37
+ border-radius: 5px;
38
+ font-size: 1rem;
39
+ transition: border-color 0.3s ease;
40
+ }
41
+ .form input:focus {
42
+ outline: none;
43
+ border-color: #457b9d;
44
+ }
45
+ .form button {
46
+ width: 100%;
47
+ padding: 12px;
48
+ margin: 15px 0;
49
+ background: #1d3557;
50
+ color: #fff;
51
+ border: none;
52
+ border-radius: 5px;
53
+ cursor: pointer;
54
+ font-size: 1rem;
55
+ transition: background-color 0.3s ease;
56
+ }
57
+ .form button:hover {
58
+ background: #457b9d;
59
+ }
60
+ .form a {
61
+ display: block;
62
+ color: #1d3557;
63
+ text-decoration: none;
64
+ margin-top: 15px;
65
+ font-size: 0.9rem;
66
+ transition: color 0.3s ease;
67
+ }
68
+ .form a:hover {
69
+ color: #457b9d;
70
+ }
71
+ .error {
72
+ color: #e63946;
73
+ margin-top: 10px;
74
+ font-size: 0.9rem;
75
+ }
76
+ </style>
77
+ </head><body>
78
+ <div class="container">
79
+ <h2>Login</h2>
80
+ <form class="form" method="POST" action="{{ url_for('login') }}">
81
+ <input type="text" name="username" placeholder="Username" required>
82
+ <input type="password" name="password" placeholder="Password" required>
83
+ <button type="submit">Login</button>
84
+ <a href="{{ url_for('signup') }}">Don't have an account? Sign up</a>
85
+ </form>
86
+ {% if error %}
87
+ <p class="error">{{ error }}</p>
88
+ {% endif %}
89
+ </div>
90
+ </body>
91
+ </html>
templates/main.html ADDED
@@ -0,0 +1,239 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Autonomous Traffic Management System</title>
7
+ <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
8
+ <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
10
+ <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyA0S_ArVIWsGXkPwpgIhCy2g4y7HlSamX8&libraries=geometry,places&callback=initMap" async defer></script>
11
+ </head>
12
+ <body>
13
+ <header>
14
+ <img src="https://cdn-icons-png.flaticon.com/512/3448/3448339.png" alt="Traffic Management Logo" class="logo">
15
+ <h1>Autonomous Traffic Management Dashboard</h1>
16
+ <div class="nav-buttons">
17
+ <a href="{{ url_for('index') }}">
18
+ <button class="nav-btn">Search place</button>
19
+ </a>
20
+ <a href="{{ url_for('main_dashboard') }}">
21
+ <button class="nav-btn">Live Traffic & Find Route</button>
22
+ </a>
23
+ </div>
24
+ <button class="login-btn" onclick="window.location.href='{{ url_for('logout') if 'username' in session else url_for('login') }}'">
25
+ {{ "Hello, " + session['username'] if 'username' in session else "Hello, Login" }}
26
+ </button>
27
+ </header>
28
+
29
+ <main>
30
+ <div class="content-container">
31
+ <!-- Find Route Section -->
32
+ <section id="route-section">
33
+ <h2>Find Route</h2>
34
+ <form id="route-form">
35
+ <label for="source-input">Source:</label>
36
+ <input id="source-input" type="text" placeholder="Enter source location">
37
+
38
+ <label for="destination-input">Destination:</label>
39
+ <input id="destination-input" type="text" placeholder="Enter destination location">
40
+
41
+ <button type="submit">Find</button>
42
+ </form>
43
+
44
+ <div id="travel-info"></div>
45
+ <div id="route-options" style="margin-top: 20px;"></div>
46
+ </section>
47
+
48
+ <!-- Traffic Stats Section -->
49
+ <section id="stats-section">
50
+ <h2>Traffic Statistics</h2>
51
+ <canvas id="traffic-stats-chart"></canvas>
52
+ </section>
53
+ </div>
54
+
55
+ <!-- Map Section -->
56
+ <section id="map-section">
57
+ <h2>Traffic Visualization</h2>
58
+ <div>
59
+ <label for="traffic-toggle">Show Traffic Layer:</label>
60
+ <input id="traffic-toggle" type="checkbox" checked>
61
+ </div>
62
+ <div id="map" style="height: 400px; width: 100%; margin-top: 10px;"></div>
63
+ </section>
64
+ </main>
65
+
66
+ <footer>
67
+ <p>Autonomous Traffic Management System</p>
68
+ </footer>
69
+
70
+ <script>
71
+ let map;
72
+ let directionsService;
73
+ let directionsRenderer;
74
+ let trafficLayer;
75
+
76
+ function initMap() {
77
+ map = new google.maps.Map(document.getElementById('map'), {
78
+ center: { lat: 18.4889, lng: 74.0246 },
79
+ zoom: 13
80
+ });
81
+
82
+ trafficLayer = new google.maps.TrafficLayer();
83
+ trafficLayer.setMap(map);
84
+
85
+ directionsService = new google.maps.DirectionsService();
86
+ directionsRenderer = new google.maps.DirectionsRenderer({ map: map });
87
+
88
+ const sourceInput = document.getElementById('source-input');
89
+ const destinationInput = document.getElementById('destination-input');
90
+
91
+ new google.maps.places.Autocomplete(sourceInput);
92
+ new google.maps.places.Autocomplete(destinationInput);
93
+
94
+ // Add event listener to the traffic toggle checkbox
95
+ const trafficToggle = document.getElementById('traffic-toggle');
96
+ trafficToggle.addEventListener('change', () => {
97
+ if (trafficToggle.checked) {
98
+ trafficLayer.setMap(map);
99
+ } else {
100
+ trafficLayer.setMap(null);
101
+ }
102
+ });
103
+ }
104
+
105
+ async function calculateAndDisplayRoute(source, destination) {
106
+ try {
107
+ const response = await directionsService.route({
108
+ origin: source,
109
+ destination: destination,
110
+ travelMode: google.maps.TravelMode.DRIVING,
111
+ provideRouteAlternatives: true
112
+ });
113
+
114
+ directionsRenderer.setDirections(response);
115
+
116
+ const routes = response.routes;
117
+ displayAvailableRoutes(routes);
118
+ } catch (error) {
119
+ alert("Error calculating route: " + error.message);
120
+ }
121
+ }
122
+
123
+ function displayAvailableRoutes(routes) {
124
+ const routeOptionsDiv = document.getElementById('route-options');
125
+ routeOptionsDiv.innerHTML = '<h3>Available Routes:</h3>';
126
+
127
+ routes.forEach((route, index) => {
128
+ const distance = route.legs[0].distance.text;
129
+ const duration = route.legs[0].duration.text;
130
+
131
+ const routeButton = document.createElement('button');
132
+ routeButton.textContent = `Route ${index + 1}: ${distance}, ${duration}`;
133
+ routeButton.addEventListener('click', () => {
134
+ directionsRenderer.setRouteIndex(index);
135
+ checkLiveTrafficOnRoute(route);
136
+ });
137
+
138
+ routeOptionsDiv.appendChild(routeButton);
139
+ });
140
+ }
141
+
142
+ async function checkLiveTrafficOnRoute(route) {
143
+ const trafficDetails = [];
144
+ const path = route.overview_path;
145
+
146
+ for (let i = 0; i < path.length; i += 1) {
147
+ const point = path[i];
148
+ try {
149
+ const trafficData = await axios.get(`https://maps.googleapis.com/maps/api/distancematrix/json`, {
150
+ params: {
151
+ origins: `${point.lat()},${point.lng()}`,
152
+ destinations: `${point.lat()},${point.lng()}`,
153
+ departure_time: 'now',
154
+ key: 'AIzaSyA0S_ArVIWsGXkPwpgIhCy2g4y7HlSamX8'
155
+ }
156
+ });
157
+
158
+ const durationInTraffic = trafficData.data.rows[0].elements[0].duration_in_traffic;
159
+ if (durationInTraffic) {
160
+ trafficDetails.push({
161
+ lat: point.lat(),
162
+ lng: point.lng(),
163
+ duration: durationInTraffic.text
164
+ });
165
+ }
166
+ } catch (error) {
167
+ console.error("Error fetching traffic data: ", error);
168
+ }
169
+ }
170
+
171
+ if (trafficDetails.length > 0) {
172
+ displayTrafficAlert(trafficDetails);
173
+ } else {
174
+ alert("This route has no significant traffic. You can proceed.");
175
+ }
176
+ }
177
+
178
+ function displayTrafficAlert(trafficDetails) {
179
+ let message = "Heavy Traffic Detected:\n\n";
180
+
181
+ trafficDetails.forEach((detail, index) => {
182
+ message += `Traffic Point ${index + 1}: Latitude: ${detail.lat}, Longitude: ${detail.lng}, Duration in Traffic: ${detail.duration}\n`;
183
+ });
184
+
185
+ message += "\nThis route has heavy traffic. Consider choosing another route.";
186
+ alert(message);
187
+ }
188
+
189
+ document.getElementById('route-form').addEventListener('submit', (e) => {
190
+ e.preventDefault();
191
+ const sourceLocation = document.getElementById('source-input').value;
192
+ const destinationLocation = document.getElementById('destination-input').value;
193
+
194
+ calculateAndDisplayRoute(sourceLocation, destinationLocation);
195
+ });
196
+
197
+ const ctx = document.getElementById('traffic-stats-chart').getContext('2d');
198
+ new Chart(ctx, {
199
+ type: 'bar',
200
+ data: {
201
+ labels: ['Intersection 1', 'Intersection 2', 'Intersection 3'],
202
+ datasets: [{
203
+ label: 'Traffic Density',
204
+ data: [30, 45, 60],
205
+ backgroundColor: ['green', 'yellow', 'red']
206
+ }]
207
+ },
208
+ options: {
209
+ responsive: true,
210
+ plugins: {
211
+ legend: {
212
+ display: true,
213
+ position: 'top',
214
+ },
215
+ tooltip: {
216
+ enabled: true,
217
+ }
218
+ },
219
+ scales: {
220
+ x: {
221
+ title: {
222
+ display: true,
223
+ text: 'Intersections',
224
+ }
225
+ },
226
+ y: {
227
+ title: {
228
+ display: true,
229
+ text: 'Traffic Density',
230
+ },
231
+ min: 0,
232
+ max: 100
233
+ }
234
+ }
235
+ }
236
+ });
237
+ </script>
238
+ </body>
239
+ </html>
templates/signup.html ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Signup</title>
7
+ <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
8
+ <style>
9
+ body {
10
+ font-family: 'Arial', sans-serif;
11
+ margin: 0;
12
+ padding: 0;
13
+ background: linear-gradient(135deg, #1d3557, #457b9d);
14
+ display: flex;
15
+ justify-content: center;
16
+ align-items: center;
17
+ height: 100vh;
18
+ color: #333;
19
+ }
20
+ .container {
21
+ background: #fff;
22
+ padding: 2rem;
23
+ border-radius: 10px;
24
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
25
+ width: 350px;
26
+ text-align: center;
27
+ }
28
+ h2 {
29
+ color: #1d3557;
30
+ margin-bottom: 1.5rem;
31
+ }
32
+ .form input {
33
+ width: 100%;
34
+ padding: 12px;
35
+ margin: 10px 0;
36
+ border: 1px solid #ccc;
37
+ border-radius: 5px;
38
+ font-size: 1rem;
39
+ transition: border-color 0.3s ease;
40
+ box-sizing: border-box;
41
+ }
42
+ .form input:focus {
43
+ outline: none;
44
+ border-color: #457b9d;
45
+ }
46
+ .form button {
47
+ width: 100%;
48
+ padding: 12px;
49
+ margin: 15px 0;
50
+ background: #1d3557;
51
+ color: #fff;
52
+ border: none;
53
+ border-radius: 5px;
54
+ cursor: pointer;
55
+ font-size: 1rem;
56
+ transition: background-color 0.3s ease;
57
+ }
58
+ .form button:hover {
59
+ background: #457b9d;
60
+ }
61
+ .form a {
62
+ display: block;
63
+ color: #1d3557;
64
+ text-decoration: none;
65
+ margin-top: 15px;
66
+ font-size: 0.9rem;
67
+ transition: color 0.3s ease;
68
+ }
69
+ .form a:hover {
70
+ color: #457b9d;
71
+ }
72
+ </style>
73
+ </head>
74
+ <body>
75
+ <div class="container">
76
+ <h2>Signup</h2>
77
+ <form class="form" method="POST" action="{{ url_for('signup') }}">
78
+ <input type="text" name="username" placeholder="Username" required>
79
+ <input type="password" name="password" placeholder="Password" required>
80
+ <input type="password" name="confirm_password" placeholder="Confirm Password" required>
81
+ <button type="submit">Signup</button>
82
+ <a href="{{ url_for('login') }}">Already have an account? Login</a>
83
+ </form>
84
+ </div>
85
+ </body>
86
+ </html>
traffic_management.db ADDED
Binary file (16.4 kB). View file