A Python package for analyzing traffic collisions along roads using GPS sampling and UK Department for Transport (DfT) collision data. This tool enables comprehensive analysis of collision patterns, including spatial distribution, temporal trends, and environmental factors.
- GPS Road Sampling: Sample GPS locations along roads at regular intervals
- Collision Detection: Find collisions within a specified radius of road sample points
- Statistical Analysis: Comprehensive analysis of collision patterns including:
- Severity breakdown (Fatal, Serious, Slight)
- Temporal analysis (hour of day, day of week)
- Weather and lighting conditions
- Distance from road calculations
- Interactive Visualization: Create interactive maps with Folium showing:
- Road geometry
- Sample points
- Color-coded collision markers by severity
- Detailed popup information for each collision
- Multiple Data Sources: Support for both manual coordinate input and OpenStreetMap (OSM) data fetching
- Python 3.8 or higher
- pip package manager
# Clone or download the repository
cd Collision-data-visualization
# Install required dependencies
pip install -r requirements.txtFor fetching road data directly from OpenStreetMap:
pip install osmnx-
Download collision data from the DfT website:
Download the latest UK road collision data:
!wget https://data.dft.gov.uk/road-accidents-safety-data/dft-road-casualty-statistics-collision-1979-latest-published-year.csv -
Define the CSV file path:
In your code, specify the path to the downloaded collision data:
collision_data_path = 'path/to/collision_data.csv' collisions = load_collision_data(collision_data_path)
For example:
# If you saved it in your project directory collisions = load_collision_data('dft-road-casualty-statistics-collision-1979-latest-published-year.csv') # Or with a full path collisions = load_collision_data('/home/user/data/dft-road-casualty-statistics-collision-1979-latest-published-year.csv')
pandas>=2.0.0
numpy>=1.24.0
geopy>=2.3.0
geopandas
shapely
folium
Optional:
osmnx # For fetching roads from OpenStreetMap
Collision-data-visualization/
├── road_analysis/ # Main package directory
│ ├── __init__.py # Package initialization
│ ├── road_sampler.py # GPS sampling along roads
│ ├── collision_analyzer.py # Collision analysis and statistics
│ ├── map_visualizer.py # Interactive map creation
│ └── utils.py # Utility functions
├── sample gps along the road.ipynb # Tutorial notebook for road sampling
├── collect collision data with multiple roads.ipynb # Example: Multiple roads analysis
├── requirements.txt # Python dependencies
├── Askew Road map.html # Example output map
├── Mile End Road map.html # Example output map
├── Cobbold Road map.html # Example output map
└── Stronsa Road map.html # Example output map
from road_analysis import RoadSampler, CollisionAnalyzer, MapVisualizer
from road_analysis.utils import load_collision_data
# Define road coordinates (longitude, latitude)
road_coords = [
(-0.2328, 51.5180),
(-0.2320, 51.5182),
(-0.2310, 51.5184),
(-0.2300, 51.5186),
# ... more coordinates
]
# Sample points along the road
sampler = RoadSampler(road_coords=road_coords, distance_interval=50)
sample_points = sampler.generate_sample_points()
# Load collision data
collisions = load_collision_data('path/to/collision_data.csv')
# Analyze collisions
analyzer = CollisionAnalyzer(
collisions_gdf=collisions,
sample_points=sample_points,
road_line=sampler.road_line,
radius=50
)
nearby_collisions = analyzer.find_nearby_collisions()
stats = analyzer.calculate_statistics()
analyzer.print_statistics()
# Create interactive map
visualizer = MapVisualizer(road_coords, sample_points, nearby_collisions)
map_obj = visualizer.build_map()
visualizer.save('output_map.html')from road_analysis import RoadSampler, CollisionAnalyzer, MapVisualizer
from road_analysis.utils import load_collision_data
# Fetch road from OSM
sampler = RoadSampler(
area_name="Hammersmith and Fulham, London, UK",
street_name="Askew Road",
distance_interval=50
)
sample_points = sampler.generate_sample_points()
# Get road coordinates for visualization
road_coords = [(point.x, point.y) for point in sampler.road_line.coords]
# Load and analyze collision data
collisions = load_collision_data('path/to/collision_data.csv')
analyzer = CollisionAnalyzer(collisions, sample_points, sampler.road_line, radius=50)
nearby_collisions = analyzer.find_nearby_collisions()
stats = analyzer.calculate_statistics()
# Create map
visualizer = MapVisualizer(road_coords, sample_points, nearby_collisions)
visualizer.save('askew_road_map.html')Handles GPS coordinate sampling along road segments.
Key Parameters:
road_coords: List of (longitude, latitude) tuples (manual mode)area_name: Area name for OSM fetching (e.g., "London, UK")street_name: Street name for OSM fetching (e.g., "Main Street")distance_interval: Distance between sample points in meters (default: 50)
Key Methods:
generate_sample_points(): Generate GPS sample points along the roadget_road_length(): Get road length in metersget_summary(): Get summary statistics
Analyzes collision data and calculates comprehensive statistics.
Key Parameters:
collisions_gdf: GeoDataFrame containing collision datasample_points: GeoDataFrame containing road sample pointsroad_line: Road LineString geometryradius: Search radius in meters (default: 50)
Key Methods:
find_nearby_collisions(): Find collisions within radiuscalculate_statistics(): Calculate comprehensive statisticsprint_statistics(): Print formatted statistics to consoleget_export_data(): Get collision data formatted for export
Statistics Provided:
- Total collisions and casualties
- Severity breakdown (Fatal/Serious/Slight)
- Time of day analysis with peak hours
- Day of week patterns
- Weather conditions distribution
- Lighting conditions distribution
Creates interactive Folium maps with collision data visualization.
Key Parameters:
road_coords: List of (lon, lat) tuples for the roadsample_points: GeoDataFrame of sample pointscollisions: GeoDataFrame of collision datazoom_start: Initial zoom level (default: 15)
Key Methods:
build_map(): Build complete map with all layerssave(filepath): Save map to HTML fileadd_road_line(): Add road geometry to mapadd_sample_points(): Add sample points to mapadd_collision_markers(): Add collision markers with popupsadd_legend(): Add map legend
Color Coding:
- 🟢 Light Blue: Sample points
- 🔴 Red: Serious collisions
- 🟠Orange: Slight collisions
- âš« Black: Fatal collisions
load_collision_data(filepath, filter_zero_vehicles=True)
- Load collision CSV and convert to GeoDataFrame
- Optionally filter out records with zero vehicles
filter_collisions(collisions_gdf, bounds=None, date_range=None, severity=None)
- Filter collisions by geographic bounds, date range, or severity
save_summary_report(analyzer, sampler, output_path)
- Save detailed text report of analysis
format_collision_data(data)
- Format statistics into human-readable summary
from road_analysis import RoadSampler, CollisionAnalyzer
from road_analysis.utils import load_collision_data
# Load collision data
collisions = load_collision_data('collisions.csv')
# Sample road and analyze
sampler = RoadSampler(
area_name="London, UK",
street_name="Mile End Road",
distance_interval=50
)
sample_points = sampler.generate_sample_points()
analyzer = CollisionAnalyzer(collisions, sample_points, sampler.road_line, radius=50)
nearby_collisions = analyzer.find_nearby_collisions()
stats = analyzer.calculate_statistics()
# Print summary
print(f"Road length: {sampler.get_road_length():.0f} meters")
print(f"Sample points: {len(sample_points)}")
print(f"Collisions found: {len(nearby_collisions)}")
analyzer.print_statistics()roads = {
'Askew Road': {
'area': 'Hammersmith and Fulham, London, UK',
'street': 'Askew Road'
},
'Mile End Road': {
'area': 'Tower Hamlets, London, UK',
'street': 'Mile End Road'
}
}
results = {}
for road_name, road_info in roads.items():
sampler = RoadSampler(
area_name=road_info['area'],
street_name=road_info['street'],
distance_interval=50
)
sample_points = sampler.generate_sample_points()
analyzer = CollisionAnalyzer(collisions, sample_points, sampler.road_line, radius=50)
analyzer.find_nearby_collisions()
results[road_name] = analyzer.calculate_statistics()
print(f"\n{road_name}:")
analyzer.print_statistics()from road_analysis.utils import filter_collisions
# Load all collision data
collisions = load_collision_data('collisions.csv')
# Filter for serious and fatal collisions in 2022
filtered_collisions = filter_collisions(
collisions,
date_range=('2022-01-01', '2022-12-31'),
severity=[1, 2] # 1=Fatal, 2=Serious
)
# Analyze filtered data
analyzer = CollisionAnalyzer(filtered_collisions, sample_points, road_line, radius=50)
analyzer.find_nearby_collisions()
analyzer.print_statistics()The collision CSV file should contain the following columns:
latitude: Collision latitudelongitude: Collision longitudecollision_index: Unique collision identifierdate: Date of collision (DD/MM/YYYY format)time: Time of collision (HH:MM format)collision_severity: 1=Fatal, 2=Serious, 3=Slightnumber_of_vehicles: Number of vehicles involvednumber_of_casualties: Number of casualtiesday_of_week: 1=Sunday through 7=Saturdayweather_conditions: Weather code (see mapping in code)light_conditions: Lighting code (see mapping in code)speed_limit: Speed limit in mph
The tool generates several types of output:
- Interactive HTML Maps: Folium maps with collision markers
- Statistics Dictionary: Python dictionary with comprehensive statistics
- Export DataFrame: Pandas DataFrame with selected collision fields
- Text Reports: Formatted text summaries
Tutorial notebook demonstrating:
- Basic road sampling workflow
- Manual coordinate input
- Point generation and visualization
- Distance calculations
Advanced notebook showing:
- Multiple road analysis
- OSM data fetching
- Comparative statistics
- Batch processing
# Fine-grained sampling (every 25 meters)
sampler = RoadSampler(road_coords=coords, distance_interval=25)
# Coarse sampling (every 100 meters)
sampler = RoadSampler(road_coords=coords, distance_interval=100)# Small radius (30 meters)
analyzer = CollisionAnalyzer(collisions, sample_points, road_line, radius=30)
# Large radius (100 meters)
analyzer = CollisionAnalyzer(collisions, sample_points, road_line, radius=100)# Create visualizer with custom zoom
visualizer = MapVisualizer(road_coords, sample_points, collisions, zoom_start=17)
# Build map with custom styling
visualizer.create_base_map()
visualizer.add_road_line(color='red', weight=5, opacity=0.8)
visualizer.add_sample_points(radius=5, color='green', opacity=0.6)
visualizer.add_collision_markers()
visualizer.add_legend()
visualizer.save('custom_map.html')If you encounter issues installing OSMnx:
# Using conda (recommended)
conda install -c conda-forge osmnx
# Or with specific versions
pip install osmnx==1.6.0If the street name isn't found:
- Check the spelling and capitalization
- Try a broader area name
- Verify the road exists in OpenStreetMap at openstreetmap.org
- Use manual coordinates as an alternative
For large collision datasets:
- Filter data by geographic bounds first
- Process roads individually
- Use chunked data loading
# Filter to specific geographic area first
bounds = (min_lon, min_lat, max_lon, max_lat)
filtered_collisions = filter_collisions(collisions, bounds=bounds)- Use appropriate sample intervals: Smaller intervals increase precision but slow processing
- Pre-filter collision data: Filter by geography and date before analysis
- Batch processing: Analyze multiple roads separately rather than simultaneously
- Save intermediate results: Cache sample points and road geometries
This tool is designed to work with UK Department for Transport (DfT) road collision data, available from:
- data.gov.uk
- Road Safety Data portal
Road geometry can be obtained from:
- OpenStreetMap (via OSMnx)
- Manual GPS tracking
- Local authority GIS data
Contributions are welcome! Please ensure:
- Code follows PEP 8 style guidelines
- All functions include docstrings
- New features include example usage
- Tests pass (if implemented)
This project is provided as-is for educational and research purposes.
For questions or issues, please contact the package maintainer.
- UK Department for Transport for collision data
- OpenStreetMap contributors for road geometry data
- Folium, GeoPandas, and OSMnx development teams
- v1.0.0: Initial release
- GPS road sampling
- Collision analysis with statistics
- Interactive map visualization
- OSM integration support
