Documentation
How to run Textile Globe, what each layer means, how it is built, and how to extend it. Everything here describes the prototype as it stands. Where something is not built, it says so.
1. User manual
Run it
You need Node.js 24.14 or newer (24.x or 26.x) and a modern browser.
git clone https://github.com/nishadiyer/World-Monitor.git
cd World-Monitor
npm ci
npm run doctor # checks Node, npm and which keys are set
npm run dev # serves http://localhost:4173
Open http://localhost:4173. Type http:// yourself: some browsers upgrade to https, which the dev server does not speak. The server listens on your machine only.
Layers
Open Data Layers and switch on rows in the Textile Supply Chain group. Click a marker to open its detail card.
| Layer | What it shows | Source |
|---|---|---|
| Cotton Regions | 28 growing areas, each with country and a short note | Curated file, approximate |
| Textile Hubs | 41 manufacturing clusters (hub level, not individual factories) | Curated file, approximate |
| Textile Ports | 36 container ports important to textile trade | Curated file, approximate |
| Trade Lanes | 11 simplified sea routes as lines (no cards) | Curated file, approximate |
| Live Vessels | Ship positions from AIS broadcasts | AISStream, live, needs a free key |
| Active Fires | Satellite fire detections | NASA FIRMS, live, needs a free key |
| Wind, radar, satellite clouds, lightning, cyclones | Weather overlays | Public weather sources, live |
Unrelated layers (flights, military, satellites, cameras and others) are hidden from the list but remain in the program. To restore one, remove its id from src/textileProfile.js.
Voice
Click GEV MIC, allow the microphone, and speak: "show cotton regions", "hide trade lanes", "take me to Tiruppur". Voice can use either of two sign-ins:
- OpenAI API key in
OPENAI_API_KEY. This is the default and is paid per use; the account must hold credit. - ChatGPT sign-in (experimental). Install the Codex command-line tool, run
codex login, restart the dev server, then choose USE CHATGPT OAUTH in POWER UP → Provider Settings. OpenAI has not documented this use of Codex credentials, so it may stop working.
Voice currently knows the textile layer names. It does not yet answer textile questions such as "which hubs are in Bangladesh".
Keys
The app starts with no keys. Add any of these free keys in POWER UP or in a private .env file (never committed):
| Variable | Unlocks | Cost |
|---|---|---|
CESIUM_ION_TOKEN | Google Photorealistic 3D, world terrain | Free for eligible personal use |
AISSTREAM_API_KEY | Live vessels | Free |
FIRMS_MAP_KEY | Active fires | Free |
TOMTOM_API_KEY | Traffic flow (layer hidden in this build) | Free tier |
MAPILLARY_CLIENT_TOKEN | Street photos (layer hidden in this build) | Free |
OPENAI_API_KEY | Voice and the AI summary readout | Metered |
Share links
The address bar encodes the camera and enabled layers. Textile layers carry stable codes 3 (cotton), 4 (hubs), 5 (lanes) and 6 (ports) in the l= parameter, so a link restores them on another machine running the same build.
2. A day in the life
An illustrative scenario, not a customer story.
Morning. A sourcing analyst opens the globe and switches on Cotton Regions and Textile Hubs. The pattern is immediate: growing areas in the United States, India, China, Brazil and Central Asia; clusters in Bangladesh, Vietnam, India, China and Turkey.
Mid-morning. She turns on Active Fires and flies to the Texas High Plains region. Any detections near the marker show on the same view. She clicks the marker for its note.
Midday. With Trade Lanes, Textile Ports and Live Vessels on, she follows the Asia to Europe lane through the Red Sea and Suez. Live ships appear on and near the line; the line itself is a simplified route, not a track.
Afternoon. She says "take me to Chattogram" and "show cotton regions" without touching the mouse, then copies the address bar to send a colleague the same view.
What she cannot do yet: filter to cargo ships only, see port congestion, or ask the globe a textile question by voice. These are on the roadmap.
3. Technical architecture
Textile Globe is a fork of God's Eye View: a browser app built with Vite and CesiumJS, plus a dev server that proxies keyed requests. The fork adds data, four layers, a panel profile and voice registration.
| Piece | Where | Role |
|---|---|---|
| Textile datasets | src/data/local_data/textile/*.geojsonl | GeoJSON Lines, one Feature per line with properties.name and properties.detail |
| Data URLs and titles | src/sources/infrastructureData.js | Resolves each layer id to its file |
| Layer factory | src/data/infrastructure.js (createTextileLayers) | Builds four layers from the shared GeoJSON layer core |
| Layer core and cards | src/data/localGeojsonCore.js | Loads files, draws markers and lines, builds detail cards |
| Catalog and state | src/app/constructCatalog.js, src/data/layerState.js, layerStateTokenReservations.json | Registers layers and assigns share-link codes |
| Panel profile | src/textileProfile.js, src/ui/layerPanel.js | Textile group on top; hides unrelated rows |
| Voice manifest | src/voice/layerManifest.js | Names and aliases for each layer so speech can toggle them |
| Server proxies | server/ | Holds keys; exposes same-origin routes |
Security model. Keys other than the three designed for the browser (Google, Cesium, Mapillary) never leave the server. The server binds to localhost, refuses cross-site requests on cost-bearing routes, and answers the ChatGPT sign-in routes to local clients only.
Quality gate. npm test runs 6,215 tests (6,214 pass, 1 skipped at last run). Layer codes and the voice schema are pinned by tests, so adding a layer means updating those pins deliberately.
4. API reference
All routes are served by the local dev server. They are for the app itself, not a public API.
| Route | Method | Returns |
|---|---|---|
/api/vessels | GET | JSON with rows (vessels), source, status (for example connecting), error, and timing fields. Needs AISSTREAM_API_KEY. |
/api/firms | GET | JSON with fetchedAt, stale, ttlMs, sources, count, fires. Without a key it answers 503 no_key. The first call after start can be slow. |
/api/firms/status | GET | Key presence, last fetch and counts |
/api/realtime/oauth-status | GET | {"available": true|false}: whether a usable Codex sign-in is present. Local clients only. |
/api/realtime/token | POST | Short-lived voice session credential. Add ?auth=oauth to use the ChatGPT sign-in. Cross-site requests are refused. |
Dataset format
{"type":"Feature","properties":{"name":"Tiruppur","detail":"India · knitwear capital, top cotton-knit exporter"},
"geometry":{"type":"Point","coordinates":[77.34,11.11]}}
Trade lanes use LineString geometry. Keep each lane from crossing the antimeridian (longitude ±180) by splitting it into two features, or it will draw the long way round the globe.
5. Add a layer
- Add a
.geojsonlfile undersrc/data/local_data/textile/. - Add its URL getter and a title in
src/sources/infrastructureData.js. - Add a
define(...)line increateTextileLayersinsrc/data/infrastructure.js. - Get the next share-link code with
npm run layer-token:next -- your-layer-id; add it tolayerStateTokenReservations.jsonand a registry entry insrc/data/layerState.js. - List it in the panel group in
src/ui/layerPanel.jsand insrc/voice/layerManifest.js. - Update the pinned counts and digests in the tests (
npm testnames each failing pin), then runnpm run format.
6. Known limits
- Textile datasets are curated by hand, approximate and static. Coordinates have not had an independent review.
- Hubs and cotton regions are area markers, not individual factories or fields.
- Trade lanes are illustrative waypoint chains, not real vessel tracks.
- The ships layer includes every vessel type.
- The title, header and first-run screen still carry the original product's wording.
- Voice depends on an experimental sign-in unless an OpenAI account with credit is used.
- The hosted copy relies on a home computer for live data: when it is off or asleep, ships, fires and weather show unavailable. It has no voice, no AI summary and no PIN gate.