#!/usr/bin/env python3 import argparse import json import os from collections import Counter import psycopg2 DB_NAME = "data_centers" POINT_TABLE = "public.us_dc_sample_geocoded" def connect(): return psycopg2.connect( host=os.environ["PGWEB_HOST"], port=os.environ["PGWEB_PORT"], user=os.environ["PGWEB_USER"], password=os.environ["PGWEB_PASSWORD"], dbname=DB_NAME, ) def load_points(conn): with conn.cursor() as cur: cur.execute( f""" select id, coalesce(provider, '') as provider, coalesce(facility_name, '') as facility_name, coalesce(city, '') as city, coalesce(state_code, '') as state_code, longitude, latitude, coalesce(geocode_source, '') as geocode_source, coalesce(geocode_precision, '') as geocode_precision, coalesce(geoid, '') as geoid from {POINT_TABLE} where longitude is not null and latitude is not null """ ) rows = cur.fetchall() points = [] for row in rows: points.append( { "id": row[0], "provider": row[1], "facility_name": row[2], "city": row[3], "state_code": row[4], "lon": float(row[5]), "lat": float(row[6]), "geocode_source": row[7], "geocode_precision": row[8], "geoid": row[9], } ) return points def compute_center(points): if not points: return 39.5, -98.35 lat = sum(p["lat"] for p in points) / len(points) lon = sum(p["lon"] for p in points) / len(points) return lat, lon def build_stats(points): by_source = Counter(p["geocode_source"] or "(blank)" for p in points) by_precision = Counter(p["geocode_precision"] or "(blank)" for p in points) return { "total": len(points), "by_source": dict(sorted(by_source.items(), key=lambda x: x[0])), "by_precision": dict(sorted(by_precision.items(), key=lambda x: x[0])), } def render_html(points, center_lat, center_lon, output_path): stats = build_stats(points) points_json = json.dumps(points) stats_json = json.dumps(stats) html = f"""