Platform concepts
The TwinPlanet pipeline has five stages: Task → Correct → Understand → Reconstruct → Simulate.
Each stage emits standard products that reference one georeferenced ground truth, so imagery,
vectors, 3D and the digital twin stay consistent.
| Stage | Input | Output |
| Task | AOI, resolution, cadence | Tasked / archive imagery |
| Correct | Raw imagery | Pansharpened, super-resolved, ortho-ready pixels |
| Understand | Corrected imagery | Segmentation, detections, change layers |
| Reconstruct | Imagery + control | Ortho, DSM/DTM, mesh, CityGML, SD/HD maps |
| Simulate | 3D + subsurface | Web 3D twin, Unreal/VR scene |
Tasking & AOIs
An Area of Interest (AOI) is defined by a polygon or bounding box plus a CRS. You can:
- New tasking — request a fresh collection (satellite, aerial or drone).
- Archive tasking — retrieve historical imagery for baselines.
- Lock an AOI — schedule periodic capture with automatic change notification.
{
"aoi": { "type": "Polygon", "coordinates": [[[9.99,53.55],[10.05,53.55],[10.05,53.58],[9.99,53.58],[9.99,53.55]]] },
"crs": "EPSG:4326",
"mode": "new", // new | archive | monitor
"sensors": ["optical","sar"],
"gsd_cm": 30,
"cadence_days": 14, // for monitor mode
"notify": "alerts@city.example"
}
Data & export formats
Everything TwinPlanet produces exports to open standards:
- Raster: GeoTIFF, Cloud-Optimized GeoTIFF, JPEG 2000
- Point cloud: LAS / LAZ
- Vector: Shapefile, GeoPackage, GeoJSON
- 3D: OBJ, FBX, glTF/GLB, 3D Tiles, CityGML
- Mobility: OpenDRIVE
- Services: WMS / WMTS / WFS, OGC API
Leads / contact API
This website ships with a small PHP endpoint that validates and stores contact requests.
POST /api/contact.php — application/json or form-encoded.
curl -X POST https://twinplanet.com/api/contact.php \
-H "Content-Type: application/json" \
-d '{
"csrf": "<token from the page>",
"name": "Jane Doe",
"email": "jane@agency.gov",
"org": "City of Hamburg",
"need": "Digital twin & simulation",
"aoi": "Hamburg, DE",
"msg": "We need a twin of the inner ring."
}'
Responses:
200 { "ok": true, "message": "Thanks — your request is in." }
422 { "ok": false, "error": "Please enter a valid work email." }
419 { "ok": false, "error": "Your session expired. Please reload." }
Requests are stored in the leads table and emailed to your team. A CSRF token
(rendered into the contact form) and a hidden honeypot field protect the endpoint.
Self-hosting
The site is plain HTML/CSS/JS with a thin PHP backend — no WordPress, no build step. Deploy it on
Ubuntu 24.04 with nginx and PHP 8.3 in a few minutes.
Full instructions: docs/INSTALL-Ubuntu-24.04.md
(also in the repository). In short:
sudo apt update && sudo apt install -y nginx php8.3-fpm php8.3-mysql mysql-server
sudo mysql < db/schema.sql
sudo cp deploy/nginx.conf /etc/nginx/sites-available/twinplanet
sudo ln -s /etc/nginx/sites-available/twinplanet /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
Prefer zero-config? Set DB_DRIVER=sqlite and the form works with no database server.
FAQ
Do I need WordPress?
No. This site is intentionally WordPress-free — pure HTML5, CSS and a small amount of PHP.
Can I host it as a static site?
Yes. Run node tools/export-static.mjs to generate a fully static _static/ build for any CDN. The contact form then needs an external endpoint (e.g. a serverless function).
Which database is required?
MySQL/MariaDB is recommended for production; SQLite works out of the box for local or small deployments.
How do I change content?
Edit the .php files in public/. Shared header/footer live in app/partials/.