The open-source platform for interactive storymaps, participatory maps, data visualization and geospatial presentations.
TalkingMaps lets you create scroll-driven story maps that combine interactive 2D and 3D maps, text narratives, multimedia, charts and data layers. It's designed for journalists, researchers, educators, planners and anyone who needs to tell a story on a map.
Key features:
http://localhost:8080)After logging in you'll see the Dashboard with:
Each story card has a three-dot menu (…) with actions: Edit, Preview, Publish/Unpublish, Duplicate, Export, Share, Delete.
In the Editor, click the gear icon () to access story-level settings:
The editor has three panels:
| Left — Slides | Center — Map | Right — Properties |
|---|---|---|
| List of slides. Drag & drop to reorder. Click + to add a new slide. | Interactive map preview. Use the toolbar to add markers, manage layers, toggle 3D. | Properties for the selected slide: layout, text, map view, styling, data, media. |
The right panel has several tabs:
Each slide can have a different layout. Choose the layout in the Content tab of the slide properties.
| Layout | Description | Map visible? |
|---|---|---|
| Cover | Centered title and text, ideal for the opening slide. Optional background image/video. | No |
| Side Left | Text panel on the left, map on the right. The default for map-driven narratives. | Yes |
| Side Right | Text panel on the right, map on the left. | Yes |
| Center | Text overlaid at the center of the map. | Yes |
| Full Map | Map fills the entire screen. No text panel. | Yes |
| Navigable Image New | Display a high-resolution image (painting, floor plan, historical map) that users can zoom and pan. Configure the image URL in the Map tab. | Yes (image) |
| 3D Globe | CesiumJS 3D globe with terrain, buildings, and 3D Tiles. Configure tileset in Media & 3D tab. | Yes (3D) |
| Point Cloud | Potree-based LiDAR / point cloud visualization. Configure the point cloud URL in Media & 3D tab. | Yes (3D) |
| Full Media | Full-screen image or video with optional text overlay at the bottom. | No |
| Text Only | Text-only slide for narratives, quotes, deep-dives. No map. | No |
| Text + Media | Split view: text on one side, image/video on the other. | No |
| Separator | Large title to divide sections of your story. | No |
The narrative text editor supports:
At the top of the narrative area you'll find quick action buttons to insert images, videos, charts or iframes with a single click.
For each slide you can set a specific map position (center, zoom, bearing, pitch):
When the viewer transitions to a slide, the map animates to its saved position. Choose the animation:
| Animation | Description |
|---|---|
| Fly To | Smooth aerial arc (default). Best for long-distance transitions. |
| Ease To | Linear smooth pan. Best for short-distance transitions. |
| Jump To | Instant, no animation. Best for same-area layout changes. |
Each slide can use a different basemap. Select it in the Map tab dropdown. This is useful for comparing satellite vs. street views across slides.
Enable a swipe comparison between two basemaps on a single slide. In the Style tab, toggle "Compare" and select a second basemap.
TalkingMaps supports multiple data source types that can be added as map layers:
| Type | Description |
|---|---|
| GeoJSON | Upload a .geojson file from your computer. Points, lines and polygons are supported. |
| WMS | Web Map Service. Enter the URL and layer name. The built-in proxy handles CORS. |
| WMTS / XYZ | Tiled services. Enter the tile URL template with {z}/{x}/{y} placeholders. |
| Vector Tiles | Mapbox Vector Tiles (MVT) from a tile server. |
| Cloud Optimized GeoTIFF | COG rasters served directly from a URL, streamed on-the-fly. |
In the Layers tab of each slide's properties, toggle which layers are visible for that specific slide. This lets you progressively reveal data as the story unfolds.
Access the global layer catalog from the user menu → Layers. Layers are shared across all your stories.
Markers are per-slide: each slide shows only its own markers. In the viewer, markers appear with a popup on click.
In the Data tab, use the Chart Wizard or paste a JSON configuration:
{
"type": "bar",
"labels": ["Jan", "Feb", "Mar", "Apr", "May"],
"data": [120, 190, 300, 250, 420],
"options": { "label": "Monthly visitors" }
}
Supported chart types: bar, line, pie, doughnut, scatter, radar, polarArea. Horizontal bars: set "horizontal": true in options.
Add dashboard-style KPI cards to any slide. In the style overrides:
{
"dashboard": [
{"label": "Population", "value": "59.5M", "icon": "people", "color": "#1a73e8"},
{"label": "Area", "value": "301,340 km²", "icon": "geo-alt", "color": "#34a853"},
{"label": "Municipalities", "value": "7,904", "icon": "building", "color": "#fbbc04"}
]
}
Embed interactive timelines powered by TimelineJS. In the Data tab, paste the timeline JSON data. Timelines are great for historical storymaps.
Customize how your layers look on the map:
Access the symbology editor from the layer panel. You can also use presets (Red-Yellow-Green, Blue-White-Red, Viridis, etc.) for quick setup.
Create slides with a 3D globe layout to show your data on a realistic 3D terrain with CesiumJS.
You can load 3D Tilesets from:
tileset.json fileVisualize LiDAR and point cloud data using Potree.
Display a high-resolution image (painting, floor plan, historical map, aerial photo) as a zoomable, pannable layer — just like a map.
Users can zoom in/out and pan the image in the viewer, just like they would with a map. This is perfect for art analysis, architectural plans, or detailed diagrams.
Enable participatory mode to let registered users add geolocated contributions (points with text, photos, videos, or audio) to your story map.
| Who | Action |
|---|---|
| Registered users | Click the Contribute button in the viewer, then click on the map to place a point. Fill in title, description, category, and optionally attach a photo, video or audio file. |
| Story owner / Admin | Review contributions in the Moderation panel (Dashboard → story menu → Moderate). Approve or reject each contribution with an optional note. |
| Everyone | See approved contributions as markers on the map with popups showing the content and media. |
The maximum file size for contribution attachments is configurable by the administrator (default: 10 MB). See System Settings.
TalkingMaps integrates AI capabilities to help you create content faster:
Configure your API keys in the user menu → Account → AI Settings. Keys are encrypted and stored per-user.
Invite other users to collaborate on your stories:
Collaborators see the story in their dashboard and can access it based on their assigned role.
Embed a story in any website using an iframe:
<iframe src="https://your-server.com?story=STORY_ID"
width="100%" height="600" frameborder="0"
allow="fullscreen"></iframe>
The embedded viewer hides the toolbar and close button for a clean reading experience.
When viewing a story, the following controls are available:
| Control | Action |
|---|---|
| Scroll wheel | Navigate between slides |
| Arrow Up / Down | Previous / next slide |
| Arrow Left / Right | Previous / next slide |
| Space | Next slide |
| Escape | Close the viewer |
| F | Toggle fullscreen |
| Map icon | Switch basemap |
| 3D icon | Toggle 2D / 3D view |
| Search icon | Geocode a place name and fly to it |
| Share icon | Copy link to share |
Access the media library from the user menu → Media Library.
Upload and manage 3D model files (glTF, GLB) for use in your stories:
.glb or .gltf fileAdmin only. User menu → Users.
| Role | Permissions |
|---|---|
| Admin | Full access: manage users, basemaps, system settings, all stories |
| Editor | Create/edit own stories, upload layers & media, collaborate on shared stories |
| Viewer | View public and shared stories only |
Actions: Create user, Disable/enable (toggle), Reset password.
Users can self-register from the login page. New users are created with the editor role by default.
Admin only. User menu → Basemaps.
Basemaps are the background maps available in all stories. Default basemaps:
To add a custom basemap: enter name, type (xyz, wms, wmts), URL, and optional config JSON (attribution, maxzoom, layers for WMS).
Admin only. User menu → Settings.
| Setting | Description | Default |
|---|---|---|
cesium_ion_token | Cesium Ion access token for 3D tilesets | (empty) |
default_storage_limit_mb | Default storage quota per user | 1024 MB |
max_upload_size_mb | Max single file upload size | 50 MB |
participatory_upload_limit_mb | Max upload size for participatory contributions | 10 MB |
analytics_enabled | Enable story view tracking | true |
# Clone the repo
git clone https://github.com/fgianoli/talkingmaps.git
cd talkingmaps
# Copy and edit the environment file
cp .env.example .env
# Edit .env: set SECRET_KEY, POSTGRES_PASSWORD, ADMIN_PASSWORD, ALLOWED_ORIGINS
# Start everything
docker compose up -d --build
# Open http://localhost:8080
# Pull latest code
git pull
# Rebuild and restart
docker compose up -d --build
For production, add a reverse proxy with HTTPS in front (Nginx Proxy Manager, Traefik, or Caddy):
# Example with Caddy (automatic HTTPS):
caddy reverse-proxy --from maps.yoursite.com --to localhost:8080
# Backup database
docker compose exec db pg_dump -U talkingmaps -d talkingmaps > backup_$(date +%Y-%m-%d).sql
# Backup media uploads
docker cp $(docker compose ps -q backend):/var/www/uploads ./uploads_backup
# Restore database
docker compose exec -T db psql -U talkingmaps -d talkingmaps < backup.sql
The WMS proxy handles CORS for external services. To add a new host, edit backend/routers/wms_proxy.py and add it to the ALLOWED_HOSTS list, then restart the backend:
docker compose restart backend
The full REST API documentation is available at /api/docs (auto-generated by FastAPI).
TalkingMaps is open source software. Made with passion by Federico Gianoli and Martino Boni (Tenoli).
GitHub
·
Report bug
·
Request feature