From Photo Metadata to 3D Map: Building an Interactive Travel Diary — DeepSeek Blog | Neura Market
    Neura MarketNeura Market/DeepSeek
    ChatGPTChatGPTClaudeClaudeGeminiGeminiCursorCursorGrokGrokPerplexityPerplexityDeepSeekDeepSeek
    CoPilotCoPilotStable DiffusionStable DiffusionMidjourneyMidjourney
    View All Directories
    OverviewRulesPromptsMCPsAgentsBlogVideosGuidesCoursesCommunityTrendingGenerate
    DeepSeekBlogFrom Photo Metadata to 3D Map: Building an Interactive Travel Diary
    Back to Blog
    From Photo Metadata to 3D Map: Building an Interactive Travel Diary
    javascript

    From Photo Metadata to 3D Map: Building an Interactive Travel Diary

    Ramiro Gómez February 5, 2026
    0 views

    How I turned GPS-tagged vacation photos into an interactive 3D journey through Spain's terrain

    --- title: From Photo Metadata to 3D Map: Building an Interactive Travel Diary published: true date: 2026-02-05 12:50:16 UTC description: How I turned GPS-tagged vacation photos into an interactive 3D journey through Spain's terrain tags: javascript, webdev, maps, visualization cover_image: https://exploring-data.com/img/preview/elevation-diary-nerja.png canonical_url: https://geeksta.net/geeklog/building-a-3d-elevation-photo-diary/ --- During a recent two-week vacation in Nerja, Spain, I took hundreds of photos with my phone. Many of them captured GPS coordinates and altitude data. Instead of letting that metadata sit unused, I decided to build an interactive 3D visualization that plots each photo on the actual terrain where it was taken. {% embed https://www.youtube.com/watch?v=6Ul_n-zxAv4 %} Quick demo of [the interactive viewer](https://exploring-data.com/map/3d/elevation-diary-nerja/) ## The Concept The idea was simple: create a chronological journey through my vacation photos, where each photo appears on a 3D terrain map at its location. As you navigate through the photos, the camera flies to each spot, showing the landscape in 3D. ## Tech Stack ### deck.gl for 3D Visualization I chose deck.gl for rendering the 3D terrain and photo markers. It's a WebGL-powered framework that handles complex 3D visualizations with impressive performance. Two key layers made this possible: **TerrainLayer** - Renders the 3D elevation map using Terrarium-format tiles from AWS: ``` const terrain = new TerrainLayer({ id: 'terrain', elevationData: 'https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png', texture: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', ... }); ``` **ScatterplotLayer** - Displays photo locations as 3D points on the terrain. I used two layers: one for visited photos (gray, smaller) and one for the current photo (orange, larger). ### Data Processing The photos' EXIF data provided latitude, longitude, altitude, and timestamps. I extracted this into a CSV file with entries sorted chronologically: ``` filestem,latitude,longitude,altitude,timestamp IMG_20260106_132810881,36.78705,-3.883663888888889,197.6,2026:01:06 13:28:12 ... ``` ## Key Features ### Smooth Camera Transitions When navigating between photos, the camera smoothly flies to the new location using deck.gl's `FlyToInterpolator`: ``` deckInstance.setProps({ initialViewState: { longitude: currentPhoto.longitude, latitude: currentPhoto.latitude, zoom: 15, bearing: 180, pitch: 40, transitionDuration: 2000, transitionInterpolator: new deck.FlyToInterpolator() } }); ``` ### Progressive Trail Visualization As you move through the photos, previously visited locations remain visible in gray, creating a visual trail of your journey. The current photo is highlighted in orange. ### Responsive Layout The interface adapts to different screen sizes: - **Landscape:** Map takes 60-70% of width, photo/controls on the right - **Portrait:** Map takes 60% of height, photo/controls below ``` @media (max-aspect-ratio: 1/1) { #app-container { flex-direction: column; } #map-container { flex: 0 0 60%; } ... } ``` ### Keyboard Navigation Keyboard shortcuts for quick navigation: - Arrow keys: Previous/Next photo - Home/End: First/Last photo - Spacebar: Play/Pause auto-advance ### Auto-Play Journey A play button advances through photos automatically (3 seconds each), creating a cinematic journey through the vacation. ## Challenges & Solutions ### GPS Altitude Accuracy Phone GPS altitude data can be unreliable, especially near sea level. I added a note in the info modal about this limitation. In future versions, I might cross-reference with the terrain elevation data to improve accuracy. ### Photo Loading Performance I selected 300 of the photos that had GPS data and created smaller web-optimized versions using [wim](https://github.com/yaph/wim) to ensure quick loading without sacrificing too much quality. ### Mobile Layout Getting the controls to fit on small portrait screens required careful tweaking of photo max-height and padding values. The final solution uses a compact info display (icons instead of labels) and reduced button spacing. ## What I Learned 1. **deck.gl is powerful but has a learning curve** - The layer system is elegant once you understand it, but proper coordinate handling and view state management took some experimentation. 2. **GPS metadata opens creative possibilities** - This project barely scratches the surface of what's possible with GPS metadata from photos. 3. **Responsive 3D is tricky** - Balancing the 3D visualization with UI controls across different screen sizes required more iteration than expected. 4. **Small touches matter** - The smooth camera transitions, progressive trail effect, and keyboard shortcuts help make the experience more engaging. ## Try It Yourself **[View the live project →](https://exploring-data.com/map/3d/elevation-diary-nerja/)** The project is built with vanilla JavaScript and deck.gl - no frameworks needed. If you have GPS-tagged photos from a trip, you could [adapt this code](https://github.com/exploringdata/website/blob/main/src/js/map/elevation-diary-nerja.js) to create your own elevation diary. Have you built something similar or have ideas for improvements? Drop a comment below! * * * **Tech Used:** - [deck.gl](https://deck.gl/) - 3D visualization - [wim](https://github.com/yaph/wim) - Image optimization - [AWS Terrain Tiles](https://registry.opendata.aws/terrain-tiles/) - Elevation data - [Esri World Imagery](https://www.arcgis.com/home/item.html?id=10df2279f9684e4a9f6a7f08febac2a9) - Satellite imagery * * * Thank you for reading! This article was written by Ramiro Gómez using open source software and the assistance of AI tools. While I strive to ensure accurate information, please verify any details independently before taking action. For more articles, visit the [Geeklog on geeksta.net](https://geeksta.net/geeklog/).

    Tags

    javascriptwebdevmapsvisualization

    Comments

    More Blog

    View all
    How I'm using ASTs and Gemini to solve the "Codebase Onboarding" problem 🧠ai

    How I'm using ASTs and Gemini to solve the "Codebase Onboarding" problem 🧠

    Hi everyone! 👋 I’m Tara, a Senior Software Engineer and Consultant. Over the years, I've jumped...

    T
    tworrell
    Local AI Will Save Us All (The Math Says So, Trust Me)ai

    Local AI Will Save Us All (The Math Says So, Trust Me)

    Every few weeks a take goes viral in tech circles making the case for ditching cloud AI and running...

    S
    Sebastian Schürmann
    Lost in the AI Hype, I Started Smallai

    Lost in the AI Hype, I Started Small

    And it helped me get back into tech without drowning TL;DR at the end Coming back to...

    R
    Rohini Gaonkar
    Building a Replay-Tested Interactive Brokers Client in Gogo

    Building a Replay-Tested Interactive Brokers Client in Go

    I wanted an IBKR library that felt like Go and had testing I could trust. So I wrote one.

    T
    Thomas Marcelis
    Playwright in Pictures: Fully Parallel Modeplaywright

    Playwright in Pictures: Fully Parallel Mode

    Playwright’s fullyParallel mode is often treated as a simple performance switch. In practice, it...

    V
    Vitaliy Potapov
    Designing a CLI for Both Humans and Agentscli

    Designing a CLI for Both Humans and Agents

    Learn how Alpic designed its CLI for both human developers and AI agents — covering tradeoffs like polling, context windows, interactivity, and statelessness.

    J
    Julien Vallini

    Stay up to date

    Get the latest DeepSeek prompts, rules, and resources delivered to your inbox weekly.

    Neura Market LogoNeura Market

    Discover the best AI prompts, plugins, and resources for DeepSeek and more.

    Content Types

    • Rules
    • Prompts
    • MCPs
    • Agents
    • Guides

    Platforms

    • ChatGPT Directory
    • Claude Directory
    • Gemini Directory
    • Cursor Directory
    • Grok Directory
    • Perplexity Directory
    • DeepSeek Directory
    • CoPilot Directory
    • Stable Diffusion Directory
    • Midjourney Directory
    • All Directories

    Resources

    • Blog
    • Documentation
    • Help Center
    • Marketplace

    Legal

    • Privacy Policy
    • Terms of Service

    © 2026 Neura Market. All rights reserved.

    |

    Not affiliated with any AI platform vendors.