Textile Globe · Documentation← Overview

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

Demo logins: there are none. The app has no sign-in. A hosted copy is public. It shows the textile layers, weather and the 3D map, and its live ships and fires work while the builder's computer is on. Voice and the AI summary only work when you run the full app yourself. A PIN-protected, always-on version is on the roadmap.

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.

LayerWhat it showsSource
Cotton Regions28 growing areas, each with country and a short noteCurated file, approximate
Textile Hubs41 manufacturing clusters (hub level, not individual factories)Curated file, approximate
Textile Ports36 container ports important to textile tradeCurated file, approximate
Trade Lanes11 simplified sea routes as lines (no cards)Curated file, approximate
Live VesselsShip positions from AIS broadcastsAISStream, live, needs a free key
Active FiresSatellite fire detectionsNASA FIRMS, live, needs a free key
Wind, radar, satellite clouds, lightning, cyclonesWeather overlaysPublic 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:

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):

VariableUnlocksCost
CESIUM_ION_TOKENGoogle Photorealistic 3D, world terrainFree for eligible personal use
AISSTREAM_API_KEYLive vesselsFree
FIRMS_MAP_KEYActive firesFree
TOMTOM_API_KEYTraffic flow (layer hidden in this build)Free tier
MAPILLARY_CLIENT_TOKENStreet photos (layer hidden in this build)Free
OPENAI_API_KEYVoice and the AI summary readoutMetered

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.

PieceWhereRole
Textile datasetssrc/data/local_data/textile/*.geojsonlGeoJSON Lines, one Feature per line with properties.name and properties.detail
Data URLs and titlessrc/sources/infrastructureData.jsResolves each layer id to its file
Layer factorysrc/data/infrastructure.js (createTextileLayers)Builds four layers from the shared GeoJSON layer core
Layer core and cardssrc/data/localGeojsonCore.jsLoads files, draws markers and lines, builds detail cards
Catalog and statesrc/app/constructCatalog.js, src/data/layerState.js, layerStateTokenReservations.jsonRegisters layers and assigns share-link codes
Panel profilesrc/textileProfile.js, src/ui/layerPanel.jsTextile group on top; hides unrelated rows
Voice manifestsrc/voice/layerManifest.jsNames and aliases for each layer so speech can toggle them
Server proxiesserver/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.

RouteMethodReturns
/api/vesselsGETJSON with rows (vessels), source, status (for example connecting), error, and timing fields. Needs AISSTREAM_API_KEY.
/api/firmsGETJSON 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/statusGETKey presence, last fetch and counts
/api/realtime/oauth-statusGET{"available": true|false}: whether a usable Codex sign-in is present. Local clients only.
/api/realtime/tokenPOSTShort-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

  1. Add a .geojsonl file under src/data/local_data/textile/.
  2. Add its URL getter and a title in src/sources/infrastructureData.js.
  3. Add a define(...) line in createTextileLayers in src/data/infrastructure.js.
  4. Get the next share-link code with npm run layer-token:next -- your-layer-id; add it to layerStateTokenReservations.json and a registry entry in src/data/layerState.js.
  5. List it in the panel group in src/ui/layerPanel.js and in src/voice/layerManifest.js.
  6. Update the pinned counts and digests in the tests (npm test names each failing pin), then run npm run format.

6. Known limits