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 — 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→London→Moscow→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> — integer-exact equirectangular projection over the sovereign geo stack (geocode · geofence · 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}