main view - displaying colored markers on the map
Data source:
I created a named query (GetAllEventLocations
) to fetch event data with location, type, and details.
Marker setup:
Using the solution from this forum post
I defined a marker template (eventMarker
) with position, color, popup, and tooltip properties. Each marker’s color corresponds to the event type:
Green - for no accident.
Yellow - for near accident.
Red - for accidents.
Transform script:
In the Map.props.layers.ui.marker
binding, I used a transform script to iterate over event data, creating color-coded markers. Popups were initially disabled to keep the map clean on load.
def transform(self, value, quality, timestamp):
import system
logger = system.util.getLogger("MAPLOGGER")
logger.info("Starting transform script for map markers.")
# Function to recursively copy the eventMarker template without modifying the original
def recursiveCopy(original):
from copy import deepcopy
from com.inductiveautomation.ignition.common.script.abc import AbstractMutableJythonMap, AbstractMutableJythonSequence
if isinstance(original, AbstractMutableJythonMap):
return {key: recursiveCopy(value) for key, value in original.iteritems()}
if isinstance(original, AbstractMutableJythonSequence):
return [recursiveCopy(item) for item in original]
return deepcopy(original)
markers = []
# Check if data was received
if not value:
logger.error("No data received from eventsDict. Check named query.")
return markers
logger.info("Data received from eventsDict: " + str(value))
# Loop over each event in the eventsDict dataset
for i, event in enumerate(value):
logger.info("Processing event " + str(i) + ": " + str(event))
# Start with a deep copy of the eventMarker to avoid modifying the original template
protoMarker = recursiveCopy(self.custom.eventMarker)
# Set the latitude and longitude for the marker based on event data, with defaults
protoMarker['lat'] = event.get('latitude', 0)
protoMarker['lng'] = event.get('longitude', 0)
# Set tooltip text to the accident name, with a default
protoMarker['tooltip']['content']['text'] = event.get('name', "Unknown Event")
# Set popup content with accident details, using defaults if data is missing
protoMarker['popup']['enabled'] = False # Disable popup by default
protoMarker['popup']['content']['text'] = "Accident Type: " + str(event.get('typeId', "N/A")) + " - " + event.get('name', "Unknown")
# Set color based on typeId for different accident severity
typeId = event.get("typeId", 0)
if typeId == 1:
protoMarker['icon']['color'] = "#00FF00" # Green for no accident
elif typeId == 2:
protoMarker['icon']['color'] = "#FFFF00" # Yellow for near accident
else:
protoMarker['icon']['color'] = "#FF0000" # Red for accident
# Add the customized marker to the list of markers
markers.append(protoMarker)
logger.info("Marker created for event " + str(i))
logger.info("Transform script completed with markers count: " + str(len(markers)))
return markers
day-specific popup - filtering the events by date
Date-specific query:
I created a second query (GetLocationForSelectedEvent
) to fetch events for a specific date using a selectedDate
parameter.
Popup view (DayDetailsPopup):
I copied the map component with configurations to DayDetailsPopup
, binding custom.eventsDict
to the date-specific query with a transform script to get the json back and passing selectedDate
as a parameter.
def transform(self, value, quality, timestamp):
filtered_events = []
for event in value:
# Only keep events with a typeId of 2 or higher (e.g., near accidents and accidents)
if event.get("typeId", 0) >= 2:
simplified_event = {
"latitude": event.get("latitude"),
"longitude": event.get("longitude"),
"name": event.get("eventName"),
"typeId": event.get("typeId")
}
filtered_events.append(simplified_event)
return filtered_events
I reused the same transform script to display the date-filtered events, maintaining the color-coding for consistency.
the results
The main map shows all events with color-coded markers. The DayDetailsPopup
map shows only events for the selected date, with popups displayed only when markers are clicked.