Inspiration
The idea for this project was born from a shared concern for personal safety during nighttime commutes. Many of us, namely one of our members, have experienced the anxiety of walking home alone, especially in unfamiliar areas or neighborhoods with a higher risk of crime at uncertain hours. To alleviate the pressure we all feel, we wanted to create a solution that empowers people to make informed decisions about their routes, prioritizing both safety and speed.
What it does
Our app is designed to help users find the safest and most efficient route to wherever they need to be. By integrating real-time data including crime statistics provided by the Toronto Public Police (type of crime, date, location) and user-generated safety reports, the app analyzes the data and suggests optimal paths that minimize exposure to potentially dangerous areas. Users also have the ability to quickly contact trusted friends/family in case of an emergency, while being given the ability to aid others through their ability to easily report incidents.
How we built it
Backend We leveraged Python and the powerful capabilities of the OpenRouteService API and python's executor subclass: ThreadPoolExecutor, to generate and optimize potential routes from one desired location to another using multithreading. Our backend was responsible for configuring routes based on key criteria, such as safety, speed, and overall efficiency. To enhance our analysis, we utilized MongoDB's NoSQL database to store and process over 40,000 crime documents from the Greater Toronto Area (GTA). This extensive database allowed us to evaluate and score the safety of generated routes. By implementing efficient parsing and processing methods, such as geospatial indexing which uses 2dsphere indices to query geographic data; we ensured that users receive the most relevant and optimal route recommendations based on their chosen preferences (e.g., "Best Overall," "Safest," or "Fastest").
Frontend The mobile interface was built using React Native, which enabled us to create a responsive, intuitive, and cross-platform application. The features include a responsive map that displays routes, a method to send emergency messages, a way to report crimes as a user, and an easy and reliable approach to find locations. The frontend was designed with user experience in mind, ensuring ease of navigation and seamless interaction with the app's features.
Data Integration We relied on publicly available crime data APIs and geolocation services to provide real-time analysis and ensure accurate route recommendations. These integrations allowed us to combine static crime data with dynamic user locations for an adaptive, personalized experience.
Mapping For displaying routes and overlaying safety information, we utilized React Native's out-of-box mapping capabilities. This allowed us to highlight key safety metrics directly on the map, such as the preferred pathways, creating an informative and interactive visual experience.
Collaboration Tools Effective teamwork was a cornerstone of our development process. We used GitHub for version control, enabling our team to collaborate smoothly, track changes, and resolve conflicts efficiently.
Challenges we ran into
The first real problem we ran into came in the form of generating unique routes. In short, we would generate random 'midpoints' along the path and would require the route to reach that point at some point. The problem was that the midpoints would generate away from a road, causing the route to start at the midpoint. To fix this problem, we would create a function that snapped the midpoints to an existing road to ensure the midpoint could be on route.
def snap_to_road(points, radius=350):
url = BASE_URL + 'v2/snap/foot-walking'
body = {"locations": points, "radius": radius }
headers = {
'Accept': 'application/json, application/geo+json, application/gpx+xml, img/png; charset=utf-8',
'Authorization': API_KEY,
'Content-Type': 'application/json; charset=utf-8'
}
response = requests.post(url, json=body, headers=headers)
if response.status_code == 200:
snapped_point = response.json()
if 'locations' in snapped_point and snapped_point['locations']:
snapped_locations = []
for location in snapped_point['locations']:
print(f"{location['location']},")
snapped_locations.append(location['location'])
return snapped_locations
else:
print(f"Failed to snap point: {points}")
return None
else:
print(f"Error: {response.status_code}, {response.text}")
return None
This solution dealt with most of the concerns we had with regards to route generation.
Surprisingly enough, the process of finding relevant crime data wasn't too hard. The part that was hard was figuring out how to get it to fit into the architecture of our openrouteservices API to generate meaningful results. Though we had a vision, conquering the trials and tribulations brought on by MongoDB, was a task in and of itself.
But if we had to pinpoint our hardest tribulation, the frontend was by far the rockiest road. Using a map wasn't bad. Displaying coordinates and then routes wasn't bad. What was bad was setting up the environment for React Native to run properly. By the time we got the environment up and running, we began running into temporary issues with our backend, so our momentary success was short-lived. Of course, in retrospect, this was probably the biggest hurdle we got over.
Other than that, we ran into some performance issues, but we tackled them fairly quickly through the use multi-threading.
Accomplishments that we're proud of
Getting the map to properly render the routes was a pretty big accomplishment. We actually celebrated for a good 2 minutes after that happened.
Another most joyous occasion was after we got the routes to generate properly. Seeing the routes actually create usable and walkable routes was quite the sight to behold.
Finally, We figured out how to optimize the crime data such that for each of the midpoints (100s-1000s of midpoints depending on the length of the trip), it would analyze over 40,000 documents to determine the safety index at each of midpoint,. We were able to reduce the time complexity of the safety index for a route from O(n*m) time to O(log(n)*m), where n = # of documents, and m = # of midpoints. We did this using geospatial indexing.
What we learned
Working on this project taught us the immense value of effective collaboration and clear communication within a team, particularly under the intense time constraints of a hackathon. We discovered how crucial it is to align on priorities, share ideas openly, and divide tasks efficiently to ensure steady progress.
We also gained valuable experience in handling real-time data and optimizing API performance. The challenges of managing large datasets and integrating multiple services pushed us to improve our technical skills and problem-solving abilities.
Most importantly, this project emphasized the need to design with empathy. By keeping the user’s safety concerns and experiences at the forefront, we were able to build an app that feels personal, intuitive, and meaningful. This perspective will continue to guide us in future projects.
What's next for Idontwanttogetstabbed
Looking ahead, we’re excited about the potential for growth and improvement. One of our key goals is to enhance our data sources by expanding coverage to include more regions and incorporating additional safety metrics, such as traffic patterns and CCTV coverage. This will make our app even more comprehensive and reliable.
We also plan to leverage machine learning to take safety recommendations to the next level. By using predictive analytics, we aim to provide proactive alerts based on emerging trends and patterns, helping users make better decisions in real time.
Another priority is fostering a sense of community within the app. We envision features that allow users to report and view real-time safety updates, such as incidents or poorly lit areas, making the platform more dynamic and user-driven.
In terms of accessibility, we'd want to be able to deploy it on Android as well as it currently on runs on iOS. We originally attempted to make the application cross-platform however Android and iOS have vastly different configurations for aspects such as map creation and accessing permissions.
Conclusion
Our project, I Don't Want to Get Stabbed, stands as a testament to the power of technology in addressing real-world safety concerns. What began as an idea rooted in personal experiences grew into a robust solution that integrates real-time data, efficient algorithms, and intuitive design to make nighttime commutes safer and more informed. We’re proud of our achievements, from optimizing crime data processing to rendering usable routes, and we’re excited to expand the app with features like machine learning-driven alerts, broader data coverage, and cross-platform accessibility to further empower users to navigate their world safely.
Log in or sign up for Devpost to join the conversation.