Geo Tile Server
The Geo Tile Server (xylem-geo) is a custom Express application that serves raster and vector map tiles for the frontend. It maintains a SQLite database of layer metadata and serves tile files from the local filesystem.
Architecture
┌──────────────────────────────────────────────┐
│ Geo Tile Server │
│ (Express :4830) │
│ │
│ ┌──────────────────────────────────────┐ │
│ │ Routes │ │
│ │ /raster/:layer/:z/:x/:y.png │ │ ← Raster tiles
│ │ /tiles/:layer.pmtiles │ │ ← Vector tiles
│ │ /layers │ │ ← Public layer list
│ │ /admin/layers (CRUD) │ │ ← Admin management
│ └──────────────────────────────────────┘ │
│ │
│ ┌──────────────┐ ┌──────────────────────┐ │
│ │ layers.db │ │ Tile Storage │ │
│ │ (SQLite) │ │ raster-tiles/ │ │
│ │ │ │ vector-tiles/ │ │
│ └──────────────┘ └──────────────────────┘ │
└──────────────────────────────────────────────┘
Routes
Public Routes
| Method | Path | Description |
|---|---|---|
GET | /raster/:layer/:z/:x/:y.png | Serve a raster tile |
GET | /tiles/:layer.pmtiles | Serve a PMTiles vector tile archive |
GET | /layers | List all enabled layers (public API) |
Admin Routes
| Method | Path | Description |
|---|---|---|
GET | /admin/layers | List all layers (including disabled) |
POST | /admin/layers | Create a new layer |
PUT | /admin/layers/:id | Update a layer |
DELETE | /admin/layers/:id | Delete a layer |
POST | /admin/upload | Upload tile files |
Tile Formats
Raster Tiles
- Standard slippy map tile format:
/{z}/{x}/{y}.png - Pre-rendered PNG images stored in directory structure
- Used for satellite imagery, zoning maps, elevation data
Vector Tiles (PMTiles)
- PMTiles format — single-file tile archives (Protomaps)
- Contains Mapbox Vector Tiles (MVT) for all zoom levels
- Efficient range-request access for individual tiles
- Used for boundary polygons, road networks, building footprints
Layer Database
The SQLite database (layers.db) stores layer metadata:
| Column | Type | Description |
|---|---|---|
id | INTEGER | Auto-incrementing primary key |
name | TEXT | Display name |
type | TEXT | raster or vector |
category | TEXT | Layer category for grouping |
tileUrl | TEXT | Tile endpoint path |
enabled | BOOLEAN | Active/visible flag |
isBaseLayer | BOOLEAN | Base map layer flag |
sortOrder | INTEGER | Display ordering |
bounds | JSON | Geographic bounding box |
minZoom | INTEGER | Minimum visibility zoom |
maxZoom | INTEGER | Maximum visibility zoom |
Configuration
| Variable | Default | Description |
|---|---|---|
PORT | 4830 | Server port |
BASE_URL | https://geo.xylem.city | Public base URL |
File Structure
xylem-geo/
├── src/
│ ├── server.ts # Express app setup, CORS, static serving
│ ├── config.ts # Environment configuration
│ ├── db/ # SQLite connection and queries
│ ├── routes/
│ │ ├── tiles.ts # Raster tile serving route
│ │ ├── raster.ts # Alternative raster route
│ │ ├── layers.ts # Public layer listing
│ │ └── admin.ts # Admin CRUD operations
│ ├── services/ # Business logic
│ └── types/ # TypeScript type definitions
├── raster-tiles/ # Raster tile PNG directories
├── vector-tiles/ # PMTiles files
└── layers.db # SQLite metadata database
Development
# Install dependencies
npm install
# Compile TypeScript
npx tsc
# Start server
node dist/server.js
# Or via PM2:
pm2 restart xylem-geo