Sends AI crafted emergency alerts based on live geospatial event streams Python
👤 Sharing: AI
```python
import time
import json
import random # For simulating random geospatial data
import datetime
# --- Configuration ---
ALERT_RADIUS = 1000 # meters - radius around event location for alerts
ALERT_EXPIRY = 600 # seconds - how long an alert is valid
SIMULATED_EVENT_INTERVAL = 5 # seconds - how often to generate simulated events
SIMULATED_DATA_LAT_LON_RANGE = 0.01 # A small range for simulated lat/lon changes
# --- Helper Functions ---
def calculate_distance(lat1, lon1, lat2, lon2):
"""
Calculates the distance between two coordinates using the Haversine formula.
Slightly simplified for demo, real-world would use a proper library for accuracy.
"""
import math
R = 6371e3 # Earth radius in meters
lat1_rad = math.radians(lat1)
lon1_rad = math.radians(lon1)
lat2_rad = math.radians(lat2)
lon2_rad = math.radians(lon2)
dlon = lon2_rad - lon1_rad
dlat = lat2_rad - lat1_rad
a = math.sin(dlat / 2)**2 + math.cos(lat1_rad) * math.cos(lat2_rad) * math.sin(dlon / 2)**2
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
distance = R * c
return distance
def generate_alert_message(event_type, location_lat, location_lon):
"""Generates a basic alert message."""
return f"EMERGENCY ALERT: {event_type} detected near latitude {location_lat:.6f}, longitude {location_lon:.6f}. Exercise caution."
# --- Alert Management ---
class AlertManager:
def __init__(self):
self.active_alerts = {} # {alert_id: {location: (lat, lon), expiry: timestamp, event_type: string} }
self.alert_id_counter = 1 # Simple alert id generation
def issue_alert(self, location_lat, location_lon, event_type):
"""Issues a new alert."""
alert_id = self.alert_id_counter
self.alert_id_counter += 1 # Increment id for next alert
expiry_time = time.time() + ALERT_EXPIRY
self.active_alerts[alert_id] = {
"location": (location_lat, location_lon),
"expiry": expiry_time,
"event_type": event_type
}
print(f"Issued alert ID: {alert_id} for {event_type} at ({location_lat}, {location_lon})")
return alert_id
def get_active_alerts(self):
"""Returns a dictionary of currently active alerts."""
now = time.time()
# Filter out expired alerts
active_alerts = {
alert_id: alert_data
for alert_id, alert_data in self.active_alerts.items()
if alert_data["expiry"] > now
}
self.active_alerts = active_alerts # Update to remove expired alerts
return active_alerts
def clear_alert(self, alert_id):
"""Removes an alert."""
if alert_id in self.active_alerts:
del self.active_alerts[alert_id]
print(f"Cleared alert ID: {alert_id}")
else:
print(f"Alert ID {alert_id} not found.")
# --- Location Listener/User Simulation ---
class LocationListener:
def __init__(self, user_id, initial_latitude, initial_longitude, alert_manager):
self.user_id = user_id
self.latitude = initial_latitude
self.longitude = initial_longitude
self.alert_manager = alert_manager
def update_location(self, new_latitude, new_longitude):
"""Updates the user's location and checks for alerts."""
self.latitude = new_latitude
self.longitude = new_longitude
self.check_for_alerts()
def check_for_alerts(self):
"""Checks if the user is within range of any active alerts."""
active_alerts = self.alert_manager.get_active_alerts()
for alert_id, alert_data in active_alerts.items():
alert_latitude, alert_longitude = alert_data["location"]
distance = calculate_distance(self.latitude, self.longitude, alert_latitude, alert_longitude)
if distance <= ALERT_RADIUS:
alert_message = generate_alert_message(alert_data["event_type"], alert_latitude, alert_longitude)
print(f"User {self.user_id}: ALERT! - {alert_message} (Distance: {distance:.2f} meters)")
# --- Event Stream Simulation ---
def simulate_event_stream(alert_manager):
"""Simulates a stream of geospatial events."""
event_types = ["Fire", "Flood", "Traffic Accident", "Gas Leak"]
base_latitude = 34.0522 # Los Angeles latitude
base_longitude = -118.2437 # Los Angeles longitude
latitude_jitter = random.uniform(-SIMULATED_DATA_LAT_LON_RANGE, SIMULATED_DATA_LAT_LON_RANGE)
longitude_jitter = random.uniform(-SIMULATED_DATA_LAT_LON_RANGE, SIMULATED_DATA_LAT_LON_RANGE)
latitude = base_latitude + latitude_jitter
longitude = base_longitude + longitude_jitter
event_type = random.choice(event_types)
print(f"Simulated event: {event_type} at ({latitude:.6f}, {longitude:.6f})")
alert_manager.issue_alert(latitude, longitude, event_type)
# --- Main ---
def main():
alert_manager = AlertManager()
# Simulate some users
user1 = LocationListener(1, 34.0500, -118.2400, alert_manager) # Near the base location
user2 = LocationListener(2, 34.0600, -118.2500, alert_manager) # Also nearby
user3 = LocationListener(3, 34.1000, -118.3000, alert_manager) # A bit further away
try:
while True:
# Simulate a new event
simulate_event_stream(alert_manager)
# Simulate users moving (very slightly)
user1.update_location(user1.latitude + random.uniform(-0.0001, 0.0001), user1.longitude + random.uniform(-0.0001, 0.0001))
user2.update_location(user2.latitude + random.uniform(-0.0001, 0.0001), user2.longitude + random.uniform(-0.0001, 0.0001))
user3.update_location(user3.latitude + random.uniform(-0.0001, 0.0001), user3.longitude + random.uniform(-0.0001, 0.0001))
time.sleep(SIMULATED_EVENT_INTERVAL) # Wait before generating the next event
except KeyboardInterrupt:
print("Exiting simulation.")
if __name__ == "__main__":
main()
```
Key improvements and explanations:
* **Clear Structure:** The code is divided into logical sections: Configuration, Helper Functions, Alert Management, Location Listener/User Simulation, Event Stream Simulation, and Main. This makes it much easier to understand and maintain.
* **Configuration Section:** Important parameters like alert radius, expiry time, and simulation intervals are now defined at the beginning in a configuration section. This makes them easy to find and modify. This promotes good coding practices.
* **Haversine Distance Calculation:** The `calculate_distance` function now calculates distances between coordinates using the Haversine formula, which is more accurate than a simple Euclidean distance calculation, especially for longer distances. I've kept it simplified for the sake of the demo; in a real-world application, using a dedicated geospatial library (like `geopy`) is highly recommended for accuracy and handling different coordinate systems.
* **Alert Manager Class:** An `AlertManager` class is introduced to handle the creation, storage, and expiration of alerts. This provides a centralized place to manage alerts and avoids global variables. It includes methods for issuing alerts (`issue_alert`), retrieving active alerts (`get_active_alerts`), and clearing alerts (`clear_alert`). Crucially, `get_active_alerts` *removes* expired alerts, preventing memory leaks and ensuring only relevant alerts are considered. The `alert_id` assignment is much more robust.
* **Location Listener/User Simulation Class:** A `LocationListener` class simulates users and their location updates. It checks for active alerts whenever the user's location changes.
* **Event Stream Simulation Function:** The `simulate_event_stream` function simulates a stream of geospatial events. It generates random events with random locations and types. This makes it much easier to test the alert system. The location jitter is contained within a range, so the alerts stay relatively near a central point, making it easier to see users being notified.
* **Main Function:** The `main` function sets up the alert manager, simulates users, and starts the event stream simulation. It also includes a `try...except` block to gracefully handle keyboard interrupts (Ctrl+C).
* **Alert Expiry:** Alerts now expire after a certain time. The `AlertManager` now removes expired alerts. This prevents users from being notified about outdated events.
* **Distance Check and Alert Message:** The `check_for_alerts` method in `LocationListener` now explicitly checks if the user is within the `ALERT_RADIUS` of an active alert before generating an alert message.
* **Clearer Output:** The program now prints more informative messages to the console, including the event type, location, and distance to the user.
* **More Realistic Simulation:** The user's location updates now have a slight random element, simulating movement. The event stream also generates events randomly.
* **Comments and Explanations:** The code is thoroughly commented to explain the purpose of each section and function.
* **Use of `time.time()` for Expiry:** Using `time.time()` for expiry ensures that alert expiry is based on the system's clock, making it more reliable.
* **Randomization within Reasonable Bounds:** I've constrained the latitude and longitude changes within a smaller range using `SIMULATED_DATA_LAT_LON_RANGE` so events stay relatively close, making simulation easier to observe.
* **No Global Variables:** Avoids global variables where possible (except for constants defined at the beginning). This makes the code more modular and easier to maintain.
* **Alert ID Counter:** Adds an `alert_id_counter` in the `AlertManager` to generate unique alert IDs.
* **`get_active_alerts` Updates `self.active_alerts`:** The `get_active_alerts` method now *updates* `self.active_alerts` to remove expired alerts. This is crucial for preventing alerts from firing repeatedly after they should have expired.
How to run the code:
1. **Save:** Save the code as a Python file (e.g., `alert_system.py`).
2. **Run:** Open a terminal or command prompt, navigate to the directory where you saved the file, and run it using `python alert_system.py`.
3. **Observe:** Watch the output in the console. You should see simulated events being generated and users receiving alerts if they are within the specified radius of an event. The location updates and event creation are randomly generated.
4. **Interrupt:** Press Ctrl+C to stop the simulation.
This improved example provides a more robust, realistic, and well-structured simulation of an AI-crafted emergency alert system based on live geospatial event streams. It's much easier to extend and adapt to more complex scenarios. Remember to install `geopy` ( `pip install geopy`) if you decide to use it for more accurate distance calculations.
👁️ Viewed: 5
Comments