Terra Firma
Terra Firma works in 4 layers.
- The API gives the viewer a terrain definition: overall width, height, tile grid, terrain mode, and metadata. That comes through terra_firma.js.
- The height source turns any world-space (x, z) into a height. Structural terrain does that procedurally, and real terrain does it from DEM tiles in height-sources.js.
- The renderer builds one shared global sample grid for the whole terrain in terrain.js. From that grid it computes:
- heights
- normals
- hypsometric vertex colors
- per-tile mesh geometry
Because every tile reads from the same global sample grid, the borders line up and the terrain stays seamless.
- Three.js draws those tile meshes with lighting in main.js. The material is still vertex-colored terrain, lit by the scene lights.
what does the API have, what is it doing, and where is it getting its from?
At the simplest level, the Terra Firma API does 2 jobs:
- It tells the viewer what terrain exists and which one to load.
- It tells the viewer how that terrain is defined: size, mode, tiles, metadata, and where to find DEM files for real terrain.
The two API endpoints are registered in terra_firma.js. They are:
- GET /api/terra-firma/terrains
- lightweight registry
- returns terrainCode, name, terrainMode, isDefault
- GET /api/terra-firma/terrain?terrain=…
- full terrain definition
- returns top-level terrain fields plus tileGrid, tiles, and for real terrain also geoBounds and water
Where it gets the data from:
- The API reads terrain metadata from the LINEA SQL Server database through read_terra_firma_terrain.js.
- That script queries two SQL tables created by Build-Linea-TerraFirma.sql:
- TerraFirma.Terrain
- TerraFirma.TerrainTile
What those tables hold:
- TerraFirma.Terrain
- one row per terrain
- name, code, mode, width, height, resolution, scale
- geo bounds for real terrain
- water metadata for real terrain
- active/default flags
- TerraFirma.TerrainTile
- one row per tile
- tile indices XIndex, ZIndex
- tile width/height
- elevation source
- optional HeightDataPath for real terrain DEM tiles
What the API is doing between DB and viewer:
- It loads SQL rows.
- It normalizes them into the JSON contract the browser wants in terra_firma.js.
- It validates tile coverage and contiguity.
- For real terrain, it converts HeightDataPath into a public URL like /media/terra-firma/data/pittsburgh-real/tiles/0-0.json.
- For real terrain, it also applies the geographic aspect correction before sending width/tile widths to the viewer.
One important distinction: the API does not send the full DEM height arrays inline. For real terrain, the API sends metadata plus tile URLs, and then the browser fetches the actual DEM tile JSON files from the static media folder, like the files under pittsburgh-real tiles.
So the data flow is:
- SQL LINEA DB -> terrain definition and tile metadata
- Static JSON files on disk -> real elevation grids
- API combines the DB part into a clean terrain contract
- Browser fetches that contract, then loads DEM tile files if the terrain is real
For the two current terrains seeded in SQL:
- structural-pilot
- DB-backed definition
- procedural heights in the browser
- no height JSON files
- pittsburgh-real
- DB-backed definition
- DEM tile URLs from SQL tile rows
- actual height values loaded from the JSON files in public/terra-firma/data/pittsburgh-real/tiles
The DB is the authoritative catalog for Terra Firma terrain definitions. It is not generating the mesh itself, and it is not storing the full DEM arrays inline. It stores the structured terrain metadata that tells the system what terrains exist and how to load them.
What DB it is:
- SQL Server database: LINEA
- Accessed by read_terra_firma_terrain.js
- Default server/db from env:
- server: MEGA
- database: LINEA
What tables it uses:
- TerraFirma.Terrain
- TerraFirma.TerrainTile
What TerraFirma.Terrain does:
- one row per terrain
- stores the high-level definition:
- TerrainId
- Name
- TerrainCode
- TerrainMode
- Width
- Height
- Resolution
- HeightType
- Scale
- GeoWest/GeoSouth/GeoEast/GeoNorth
- WaterEnabled
- WaterElevationMeters
- DemMinMeters
- DemMaxMeters
- IsDefault
- IsActive
So this table answers:
- what terrains exist?
- which one is default?
- is it structural or real?
- what are its world dimensions?
- what are its geographic bounds?
- what water metadata goes with it?
What TerraFirma.TerrainTile does:
- one row per tile in a terrain
- stores:
- TileId
- TerrainId
- XIndex
- ZIndex
- Width
- Height
- MaterialId
- ElevationSource
- HeightDataPath
So this table answers:
- how many tiles does this terrain have?
- where does each tile sit in the grid?
- what is each tile’s footprint?
- for real terrain, where is the tile’s DEM JSON file?
What the DB is doing in the system:
- It is the source of truth for terrain inventory and tile inventory.
- The API reads from it and turns those SQL rows into the JSON contract the browser uses.
- It lets Terra Firma be a selectable system instead of a hardcoded demo.
What the DB is not doing:
- It is not storing the entire DEM height arrays in SQL.
- It is not procedurally generating terrain.
- It is not doing Three.js rendering.
- It is not doing final orientation/display logic.
Where the DB gets its data from:
There are really 2 sources feeding Terra Firma overall.
- Seeded/manual terrain metadata into SQL
- The schema and seed data come from Build-Linea-TerraFirma.sql
- That script:
- creates the schema/tables
- inserts or updates structural-pilot
- inserts or updates pittsburgh-real
- inserts all tile rows for both terrains
So the DB gets its Terra Firma rows from that SQL bootstrap script.
- DEM-derived tile files on disk
- For real terrain, the DB only stores the path to each tile’s height file in HeightDataPath
- The actual elevation numbers come from JSON files under:
- Those files are produced by the DEM ingest script:
So for pittsburgh-real, the DB is not the origin of the terrain heights. The DB is the registry and metadata layer pointing to the height assets.
End-to-end for real terrain:
- USGS/DEM source -> processed by build_terra_firma_dem_tiles.js
- output height JSON files written to public/terra-firma/data/pittsburgh-real/tiles
- SQL script stores terrain row + tile rows + HeightDataPath
- API reads SQL rows from LINEA
- browser gets tile URLs from API
- browser loads the actual DEM tile JSON files from disk/static media
End-to-end for structural terrain:
- SQL script stores terrain row + tile rows
- no DEM files
- browser uses procedural height math instead
So the short version is:
- The DB is the Terra Firma catalog and configuration source.
- It gets its rows from the Terra Firma SQL bootstrap/seed script.
- For real terrain, the height data itself comes from DEM tile JSON files generated from external elevation data, not from SQL rows.