Leo,
I'm pretty new to GeoEvent server, but I think you would need to create a new input connector that parses the JSON structure according to what you describe. We are setting up a new 10.7 Pre Release GeoEvent server and the GTFS connector is not working for some reason. To get around it I created the Python script below. This runs through Task Scheduler and polls the JSON web service every 5 minutes or so, and then parses the bus locations out to individual streams (the source just has everything in one JSON object). The resulting individual stream is pushed through a TCP port that GeoEvent server picks up through a TCP input connector.
The main point is that the code (Python in this case) is parsing the JSON object for specific values. First, the JSON feed is dumped into a list (output = json.loads(data)) and then each individual 'entity' is selected for individual variables (i.e. bus["vehicle"]["trip"]["trip_id])). I think this is what you mean by "flattening out" the JSON data. In your case you could cycle through the status changes (not sure if there is more than one) using ' for status in output['status_changes']:' and get a coordinate using status["event_location"]["geometry"]["coordinates"][0].
To set this up through an input connector itself would mean coding it in Java, something I've still got to figure out.
Good luck, Jeff.
import arcpy
import urllib, json, os
import time
import socket
from datetime import datetime, timedelta
def GetBusLocations():
## Create socket connection to hostname/port on which a TCP GeoEvent input is running
host = {Your service IP}
port = 5563
tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpSocket.connect((host, port))
JsonWebData = "https://transitdata...?format=json"
from urllib import urlopen
src = None
try:
while True:
src = urlopen(JsonWebData)
data = src.read()
output = json.loads(data)
## Loop through feed entities
for bus in output['entity']:
tripId = str(bus["vehicle"]["trip"]["trip_id"])
busId = str(bus["vehicle"]["vehicle"]["id"])
routeId = str(bus["vehicle"]["trip"]["route_id"])
startDate = str(bus["vehicle"]["trip"]["start_date"])
startTime = str(bus["vehicle"]["trip"]["start_time"])
timeStamp = str(bus["vehicle"]["timestamp"])
latitude = str(bus["vehicle"]["position"]["latitude"])
longitude = str(bus["vehicle"]["position"]["longitude"])
bearing = str(bus["vehicle"]["position"]["bearing"])
speed = str(bus["vehicle"]["position"]["speed"])
status = str(bus["vehicle"]["current_status"])
stopId = str(bus["vehicle"]["stop_id"])
## Subtract 7 hours from timestamp to equate to local time.
dTS = (datetime.utcfromtimestamp(float(timeStamp)) - timedelta(hours=7)).strftime('%Y-%m-%d %H:%M:%S')
## For TESTING
## print("Bus ID: %s" % busId)
## print("Route: %s" % routeId)
## print("TripID: %s" % tripId)
## print("Date: %s" % startDate)
## print("Timestamp: %s" % timeStamp)
## print("Lat: %s" % latitude)
## print("Long: %s" % longitude
## print("Bearing: %s" % bearing)
## print("Speed: %s" % speed)
## print("Status: %s" % status)
## print("Stop: %s" % stopId)
if busId is not None and startDate is not None and startTime is not None:
## Build fields to send to GeoEvent.
msg = tripId + "," + \
busId + "," + \
routeId + "," + \
startDate + " " + startTime + "," + \
dTS + "," + \
latitude + "," + \
longitude + "," + \
bearing + "," + \
speed + "," + \
status + "," + \
stopId + "\n"
## For TESTING
#print(msg)
## Send message to TCP socket
tcpSocket.send(msg)
time.sleep(5)
except:
time.sleep(30)
pass
finally:
if src:
src.close()
if __name__ == "__main__":
GetBusLocations()