code wiki / _hdl_build / nx_geo_mapsvg.nx

nx_geo_mapsvg.nx source

↩ module page · 115 lines · 7693 B

1// nx_geo_mapsvg.nx -- GEO-007: the SOVEREIGN MAP SURFACE. Renders real geo data (gazetteer cities, 2// a geofence, a route) to an HTML page with INLINE SVG -- a vector map drawn bits-up from Nishi data 3// with ZERO third-party map library (no Leaflet / Mapbox / Google / OpenLayers; SVG is the last-mile 4// web standard, like HTML/HTTP). Equirectangular projection (integer microdegrees -> viewport px). 5// Writes sites/nishifamily/maps/index.html so nx_sites_daemon serves it at nishifamily.com/maps. 6// This is the "privacy + sovereign map" surface: the geometry, projection and styling are all ours. 7import "nx_syscalls.nx" 8import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc) 9const K_MAGIC_180000000: i64 = 180000000 10const K_MAGIC_360000000: i64 = 360000000 11const K_MAGIC_90000000: i64 = 90000000 12const K_MAGIC_51505000: i64 = 51505000 13const K_MAGIC_127000: i64 = 127000 14const K_MAGIC_35676000: i64 = 35676000 15const K_MAGIC_139650000: i64 = 139650000 16const K_MAGIC_40712000: i64 = 40712000 17const K_MAGIC_74006000: i64 = 74006000 18const K_MAGIC_33868000: i64 = 33868000 19const K_MAGIC_151209000: i64 = 151209000 20const K_MAGIC_48856000: i64 = 48856000 21const K_MAGIC_2352000: i64 = 2352000 22const K_MAGIC_30044000: i64 = 30044000 23const K_MAGIC_31235000: i64 = 31235000 24const K_MAGIC_22906000: i64 = 22906000 25const K_MAGIC_43172000: i64 = 43172000 26const K_MAGIC_55755000: i64 = 55755000 27const K_MAGIC_37617000: i64 = 37617000 28const K_MAGIC_30000000: i64 = 30000000 29 30func m_w(fd: i64, s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(fd, s, n); return 0 } 31// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer 32// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the 33// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls). 34// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign. 35func m_n(fd: i64, v: i64) -> i64 { nxi_fd(fd, v); return 0 } 36// equirectangular projection: microdegree lon/lat -> viewport px (W=960, H=480). 37func m_px(lon_md: i64) -> i64 { return (lon_md + K_MAGIC_180000000) * 960 / K_MAGIC_360000000 } 38func m_py(lat_md: i64) -> i64 { return (K_MAGIC_90000000 - lat_md) * 480 / K_MAGIC_180000000 } 39func main(argc: i64, argv: *i64) -> i64 { 40 // 8 real gazetteer cities (microdegrees). 41 let nm: *i64 = sys_mmap(8 * 8) as *i64 42 let lat: *i64 = sys_mmap(8 * 8) as *i64 43 let lon: *i64 = sys_mmap(8 * 8) as *i64 44 nm[0] = "London" as *u8 as i64; lat[0] = K_MAGIC_51505000; lon[0] = 0 - K_MAGIC_127000 45 nm[1] = "Tokyo" as *u8 as i64; lat[1] = K_MAGIC_35676000; lon[1] = K_MAGIC_139650000 46 nm[2] = "New York" as *u8 as i64; lat[2] = K_MAGIC_40712000; lon[2] = 0 - K_MAGIC_74006000 47 nm[3] = "Sydney" as *u8 as i64; lat[3] = 0 - K_MAGIC_33868000; lon[3] = K_MAGIC_151209000 48 nm[4] = "Paris" as *u8 as i64; lat[4] = K_MAGIC_48856000; lon[4] = K_MAGIC_2352000 49 nm[5] = "Cairo" as *u8 as i64; lat[5] = K_MAGIC_30044000; lon[5] = K_MAGIC_31235000 50 nm[6] = "Rio" as *u8 as i64; lat[6] = 0 - K_MAGIC_22906000; lon[6] = 0 - K_MAGIC_43172000 51 nm[7] = "Moscow" as *u8 as i64; lat[7] = K_MAGIC_55755000; lon[7] = K_MAGIC_37617000 52 53 let fd: i64 = sys_openat_wr("sites/nishifamily/maps/index.html" as *u8, 420) 54 if fd < 0 { m_w(1, "MAPSVG FATAL cannot open output\n" as *u8); sys_exit(1); return 1 } 55 56 m_w(fd, "<!DOCTYPE html>\n<html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><title>Nishi Maps</title>\n" as *u8) 57 m_w(fd, "<style>body{font-family:-apple-system,Segoe UI,Roboto,sans-serif;margin:0;background:#0b1020;color:#e8ecf5}header{padding:18px 24px}h1{margin:0;font-size:1.5rem}.tag{color:#8fa3c8;font-size:.95rem;margin-top:4px}.wrap{padding:0 24px 24px}svg{width:100%;height:auto;background:#0e1730;border:1px solid #22305a;border-radius:8px}.foot{padding:0 24px 28px;font-size:.8rem;color:#6b7aa3}.legend{font-size:.85rem;color:#9fb0d6;margin:10px 0}.legend span{display:inline-block;margin-right:18px}.dot{display:inline-block;width:9px;height:9px;border-radius:50%;vertical-align:middle;margin-right:5px}</style></head><body>\n" as *u8) 58 m_w(fd, "<header><h1>Nishi Maps</h1><div class=\"tag\">A sovereign map surface &mdash; vector-rendered bits-up from Nishi geo data. No Leaflet, no Mapbox, no Google, no third-party map library.</div></header>\n" as *u8) 59 m_w(fd, "<div class=\"wrap\"><div class=\"legend\"><span><i class=\"dot\" style=\"background:#5cc8ff\"></i>gazetteer city</span><span><i class=\"dot\" style=\"background:#ffd166\"></i>route (NYC&rarr;London&rarr;Moscow&rarr;Tokyo)</span><span><i class=\"dot\" style=\"background:#ff6b9d\"></i>geofence (London)</span></div>\n" as *u8) 60 m_w(fd, "<svg viewBox=\"0 0 960 480\" xmlns=\"http://www.w3.org/2000/svg\">\n" as *u8) 61 62 // graticule: lon meridians every 30deg, lat parallels every 30deg. 63 var g: i64 = 0 - K_MAGIC_180000000 64 while g <= K_MAGIC_180000000 { 65 let x: i64 = m_px(g) 66 m_w(fd, "<line x1=\"" as *u8); m_n(fd, x); m_w(fd, "\" y1=\"0\" x2=\"" as *u8); m_n(fd, x) 67 m_w(fd, "\" y2=\"480\" stroke=\"#1c2950\" stroke-width=\"1\"/>\n" as *u8) 68 g = g + K_MAGIC_30000000 69 } 70 var p: i64 = 0 - K_MAGIC_90000000 71 while p <= K_MAGIC_90000000 { 72 let y: i64 = m_py(p) 73 m_w(fd, "<line x1=\"0\" y1=\"" as *u8); m_n(fd, y); m_w(fd, "\" x2=\"960\" y2=\"" as *u8); m_n(fd, y) 74 m_w(fd, "\" stroke=\"#1c2950\" stroke-width=\"1\"/>\n" as *u8) 75 p = p + K_MAGIC_30000000 76 } 77 // equator highlight. 78 m_w(fd, "<line x1=\"0\" y1=\"240\" x2=\"960\" y2=\"240\" stroke=\"#2a3a6e\" stroke-width=\"1.5\"/>\n" as *u8) 79 80 // route polyline: NYC(2) -> London(0) -> Moscow(7) -> Tokyo(1). 81 m_w(fd, "<polyline fill=\"none\" stroke=\"#ffd166\" stroke-width=\"2\" stroke-dasharray=\"6 4\" points=\"" as *u8) 82 let rt: *i64 = sys_mmap(4 * 8) as *i64 83 rt[0] = 2; rt[1] = 0; rt[2] = 7; rt[3] = 1 84 var ri: i64 = 0 85 while ri < 4 { 86 let c: i64 = rt[ri] 87 m_n(fd, m_px(lon[c])); m_w(fd, "," as *u8); m_n(fd, m_py(lat[c])); m_w(fd, " " as *u8) 88 ri = ri + 1 89 } 90 m_w(fd, "\"/>\n" as *u8) 91 92 // geofence: dashed circle around London (idx 0), ~40px radius. 93 m_w(fd, "<circle cx=\"" as *u8); m_n(fd, m_px(lon[0])); m_w(fd, "\" cy=\"" as *u8); m_n(fd, m_py(lat[0])) 94 m_w(fd, "\" r=\"40\" fill=\"#ff6b9d22\" stroke=\"#ff6b9d\" stroke-width=\"1.5\" stroke-dasharray=\"4 3\"/>\n" as *u8) 95 96 // city markers + labels. 97 var i: i64 = 0 98 while i < 8 { 99 let x: i64 = m_px(lon[i]) 100 let y: i64 = m_py(lat[i]) 101 m_w(fd, "<circle cx=\"" as *u8); m_n(fd, x); m_w(fd, "\" cy=\"" as *u8); m_n(fd, y) 102 m_w(fd, "\" r=\"5\" fill=\"#5cc8ff\" stroke=\"#0b1020\" stroke-width=\"1.5\"/>\n" as *u8) 103 m_w(fd, "<text x=\"" as *u8); m_n(fd, x + 9); m_w(fd, "\" y=\"" as *u8); m_n(fd, y + 4) 104 m_w(fd, "\" fill=\"#cdd9f5\" font-size=\"13\" font-family=\"sans-serif\">" as *u8) 105 m_w(fd, nm[i] as *u8); m_w(fd, "</text>\n" as *u8) 106 i = i + 1 107 } 108 m_w(fd, "</svg></div>\n" as *u8) 109 m_w(fd, "<p class=\"foot\">Rendered bits-up by <code>nx_geo_mapsvg</code> &mdash; integer-exact equirectangular projection over the sovereign geo stack (geocode &middot; geofence &middot; routing). Served by the Nishi sites daemon (TLS 1.3 + Ed25519). nishifamily.com/maps</p>\n" as *u8) 110 m_w(fd, "</body></html>\n" as *u8) 111 sys_close(fd) 112 m_w(1, "MAPSVG wrote sites/nishifamily/maps/index.html cities=8 route=4 geofence=1 verdict=GREEN\n" as *u8) 113 sys_exit(0) 114 return 0 115}