Building a Harford County Accident Tracker with Flask and Folium

in Regional Press18 days ago

I recently set up a server on IONOS to create a simple yet effective local accident-reporting web application. This tool allows community members to easily report traffic accidents and visualize them in real-time on an interactive map.

🚧 Why This Matters

Real-time accident reporting helps locals avoid traffic congestion, improves community safety, and raises awareness about accident-prone areas.

⚙️ Technologies Used

  • Python (Flask): Lightweight web framework
  • Folium: Interactive mapping in Python
  • Simple Text Storage: For ease and simplicity (accident_reports.txt)

🛠️ Application Features

🔸 Report Submission

Residents submit accident reports via a straightforward web form.

🔸 Report Storage

Reports are stored in a local file for easy retrieval.

🔸 Interactive Mapping

Folium dynamically visualizes accident locations.


📌 Core Application Code

Below is the full, self-contained Flask application code that handles accident reporting, storage, and map visualization:

from flask import Flask, render_template_string, request, redirect, url_for
import folium
import os

app = Flask(__name__)

REPORTS_FILE = 'accident_reports.txt'

# Load all accident reports
def load_reports():
    if not os.path.exists(REPORTS_FILE):
        return []
    with open(REPORTS_FILE, 'r') as f:
        lines = f.readlines()
    reports = []
    for line in lines:
        try:
            lat, lng, desc = line.strip().split('|', 2)
            reports.append((float(lat), float(lng), desc))
        except:
            continue
    return reports

# Save new accident report
def save_report(lat, lng, desc):
    with open(REPORTS_FILE, 'a') as f:
        f.write(f"{lat}|{lng}|{desc}\n")

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        lat = request.form.get('lat')
        lng = request.form.get('lng')
        desc = request.form.get('description')
        if lat and lng and desc:
            save_report(lat, lng, desc)
        return redirect(url_for('index'))

    # Generate interactive map
    m = folium.Map(location=[39.5362, -76.3526], zoom_start=11)
    for lat, lng, desc in load_reports():
        folium.Marker([lat, lng], popup=desc).add_to(m)
    map_html = m._repr_html_()

    # Simple HTML interface
    html = '''
    <!DOCTYPE html>
    <html>
    <head>
        <title>Harford County Accident Map</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <style>
            body { font-family: Arial, sans-serif; background: #f4f6fa; }
            .container { max-width: 420px; margin: auto; padding: 24px; }
            input, textarea { width: 100%; margin-bottom: 8px; padding: 6px; }
            button { padding: 8px; width: 100%; background: #4267B2; color: white; border: none; }
        </style>
    </head>
    <body>
        <div class="container">
            <h2>Report an Accident</h2>
            <form method="POST">
                <input type="number" step="any" name="lat" placeholder="Latitude" required>
                <input type="number" step="any" name="lng" placeholder="Longitude" required>
                <textarea name="description" placeholder="Description" required></textarea>
                <button type="submit">Submit Report</button>
            </form>
            <div>{{ map_html|safe }}</div>
        </div>
    </body>
    </html>
    '''
    return render_template_string(html, map_html=map_html)

if __name__ == '__main__':
    app.run(debug=True)
Sort: