#!/usr/bin/python3 import requests import json cameras = [] res = requests.get("https://chartexp1.sha.maryland.gov/CHARTExportClientService/getCameraMapDataJSON.do") res.raise_for_status() # { # "error": null, # "data": [ # { # "description": "I-270 & Old Hundred Rd (MD 109)(CAM 165)", # "lat": 39.2773, # "lon": -77.3236, # "cctvIp": "strmr5.sha.maryland.gov", # "milePost": 22.27, # "cameraCategories": [ # "Wash. DC" # ], # "routeNumber": 270, # "commMode": "ONLINE", # "routePrefix": "IS", # "routeSuffix": "", # "opStatus": "OK", # "publicVideoURL": "https://chart.maryland.gov/Video/GetVideo/7a00a1dc01250075004d823633235daa", # "lastCachedDataUpdateTime": 1706950514352, # "name": "I-270 & Old Hundred Rd (MD 109)", # "id": "7a00a1dc01250075004d823633235daa" # }, for c in res.json()['data']: try: # # 50-ish are marginal; let's ignore that and put 'em on the map anyway # if not c['commMode'] == "ONLINE": # print("warn: camera offline; ignoring:", c) # continue # if not c['opStatus'] == "OK": # print("warn: camera not ok; ignoring:", c) # continue cameras.append({ "type": "Feature", "geometry": { "type": "Point", "coordinates": [c['lon'], c['lat']], # yes, [lon, lat] since it's [x, y] }, "properties": { "name": c['description'], "views": [ { 'hasVideo': True, 'src': f"https://{c['cctvIp']}/rtplive/{c['id']}/playlist.m3u8", }, # { # 'hasVideo': False, # 'src': c['imageUrl'], # } ] }, }) except Exception as e: print(c) raise e geojson = { "type": "FeatureCollection", "features": cameras, } with open("data.geojson", "w") as f: f.write(json.dumps(geojson)) print(f"{len(cameras)} locations found")