Creating 3D world from google maps with three js grid

I want to be able to build an app that enables me to navigate a specific area and use three js to place terrain shape grids, then different symbols like three js 3d annotations, objectes etc.
is there a demo or something that someone alread done?

Here is a link to an AI studio tutorial of how to achieve this. Also, it gives you a chance to check out the ease of use and helpful guides, so you can create and learn at the same time. :grinning_face: Hope this helps, and good luck on your project!

~Cmd.Proton🖖

thank you for the tutorial - very creative - but i followed exact instructions already and didnt manage to achieve the result i’ve uploaded above.
If someone can generate an app with placeholders for API keys and Map id in the first page - i would appreciate that

Alrighty, sorry you didn’t get the desired result you were looking for. I know that can be frustrating…heh j/k. I think I’m getting my Gemini impression down, though! :thinking: Give me a few; I think I know how to go about this. Also, I have nothing to do atm and was looking for something to work on. Are you making a stand-alone app for Android/iOS, or is it web-based?

~Cmd.Proton🖖

Also do you think you will want to make this into a camera-based AR with WebXR?
You still convert (lat,lng,alt) some 3D frame. You just swap the map’s camera & projection with AR session’s camera pose, then fake a ground plane by aligning GPS + compass. we could add this now if it’s the end goal and just make it into a switch in the same app.

Hey dimleyk, I’m back and hope this works for you. I thought I might have more time to work on it. Let me know how it goes. If it doesn’t get you to where you were going, I may be able to try again tomorrow; seems like a fun project anyway!

*Edit I’m going to keep editing this as i get time. This is still bringing 5 errors. I think I know what to do next, but it will have to wait till morning. I’ve not worked with this before so :bear: with me. If anyone has any suggestions, I’m now invested in this project as well :laughing: making the cam AR WebXR has intrigued me. Should be straightforward if we get the base down.

~Cmd.Proton out :vulcan_salute:

  • Create a new folder, save this file as index.html.
  • In the <script src="https://maps.googleapis.com/maps/api/js?..."> tag:
  • Replace YOUR_GOOGLE_MAPS_API_KEY_HERE with your own Google Maps JS API key.
  • Replace YOUR_GOOGLE_MAP_ID_HERE with your Map ID (from Google Cloud console).
  • Optional: also replace "YOUR_GOOGLE_MAP_ID_HERE" in the new google.maps.Map({ mapId: ... }) config; or just keep the same string for clarity.
  • Run with any static server, e.g.:
  • npx serve .
  • or VSCode Live Server
  • You’ll see:
  • A Google Map centered on SF.
  • A floating, spinning 3D sphere above that coordinate.
  • To move the marker:
  • Edit TEST_MARKER.lat, .lng, and .altitudeMeters.
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Google Maps + Three.js WebGL Overlay Starter</title>
  <meta name="viewport" content="width=device-width, initial-scale=1" />

  <style>
    html, body {
      margin: 0;
      padding: 0;
      width: 100%;
      height: 100%;
      overflow: hidden;
      font-family: system-ui, sans-serif;
      background: #000;
    }
    #map {
      width: 100%;
      height: 100%;
    }
    #debug-overlay {
      position: absolute;
      top: 10px;
      left: 10px;
      padding: 6px 10px;
      background: rgba(0,0,0,0.65);
      color: #fff;
      font-size: 12px;
      border-radius: 4px;
      pointer-events: none;
    }
  </style>

  <!-- Three.js (ESM is nice, but we'll just use UMD for simplicity) -->
  <script src="https://unpkg.com/three@0.161.0/build/three.min.js"></script>
</head>
<body>
  <div id="map"></div>
  <div id="debug-overlay">
    Google Maps + Three.js WebGLOverlayView<br />
    ➜ Put your API key & Map ID in the script tag URL.
  </div>

  <!--
    IMPORTANT: Replace:
      - YOUR_GOOGLE_MAPS_API_KEY_HERE
      - YOUR_GOOGLE_MAP_ID_HERE
  -->
  <script
    src="https://maps.googleapis.com/maps/api/js?key=YOUR_GOOGLE_MAPS_API_KEY_HERE&callback=initMap&v=beta&map_ids=YOUR_GOOGLE_MAP_ID_HERE"
    defer
  ></script>

  <script>
    // ============================================================
    // CONFIG: CAMERA + SAMPLE MARKER POSITION
    // ============================================================
    const INITIAL_CAMERA = {
      lat: 37.7749,   // SF placeholder
      lng: -122.4194,
      tilt: 60,
      heading: 0,
      zoom: 17
    };

    // Example "AR" marker position and altitude (meters)
    const TEST_MARKER = {
      lat: 37.7749,
      lng: -122.4194,
      altitudeMeters: 50
    };

    // ============================================================
    // GOOGLE MAPS INIT (called by JS API callback)
    // ============================================================
    let map;

    function initMap() {
      map = new google.maps.Map(document.getElementById("map"), {
        center: { lat: INITIAL_CAMERA.lat, lng: INITIAL_CAMERA.lng },
        zoom: INITIAL_CAMERA.zoom,
        heading: INITIAL_CAMERA.heading,
        tilt: INITIAL_CAMERA.tilt,
        mapId: "YOUR_GOOGLE_MAP_ID_HERE" // <-- redundant but explicit
      });

      initWebGLOverlay();
    }

    // ============================================================
    // WEBGL OVERLAY + THREE.JS
    // ============================================================
    function initWebGLOverlay() {
      const overlay = new google.maps.WebGLOverlayView();

      let scene, camera, renderer;
      let testMarker;

      overlay.onAdd = () => {
        // Set up Three.js scene + camera
        scene = new THREE.Scene();
        camera = new THREE.PerspectiveCamera();

        // Simple lights
        const ambient = new THREE.AmbientLight(0xffffff, 0.6);
        scene.add(ambient);

        const directional = new THREE.DirectionalLight(0xffffff, 0.8);
        directional.position.set(0, 1, 0);
        scene.add(directional);

        // ========================================================
        // EXAMPLE: ONE 3D MARKER AT GEO POSITION
        // ========================================================
        const markerGeometry = new THREE.SphereGeometry(5, 16, 16);
        const markerMaterial = new THREE.MeshStandardMaterial({
          color: 0xff3366,
          metalness: 0.2,
          roughness: 0.4
        });

        testMarker = new THREE.Mesh(markerGeometry, markerMaterial);
        scene.add(testMarker);
      };

      // Google hands us the WebGL context here
      overlay.onContextRestored = ({ gl }) => {
        renderer = new THREE.WebGLRenderer({
          canvas: gl.canvas,
          context: gl,
          antialias: true
        });
        renderer.autoClear = false;
      };

      overlay.onDraw = ({ gl, transformer }) => {
        if (!renderer || !scene || !camera) return;

        // ========================================================
        // GEO → CLIP SPACE TRANSFORM
        // ========================================================
        // Compute model matrix for our marker using transformer.
        // This converts a LatLng + altitude into a matrix relative
        // to the map camera.
        const latLngAltitude = {
          lat: TEST_MARKER.lat,
          lng: TEST_MARKER.lng,
          altitude: TEST_MARKER.altitudeMeters
        };

        const modelMatrix = transformer.fromLatLngAltitude(latLngAltitude);

        // Write the model matrix into the Three.js object
        testMarker.matrixAutoUpdate = false;
        testMarker.matrix.fromArray(modelMatrix);

        // Simple idle animation: spin around Y
        testMarker.rotation.y += 0.01;

        // Let Google Maps set camera parameters for us
        const viewProjectionMatrix = transformer.getCameraMatrix();
        camera.projectionMatrix.fromArray(viewProjectionMatrix);

        // Render
        renderer.state.reset();
        renderer.render(scene, camera);

        // Tell Maps API we're done
        renderer.resetState();
      };

      overlay.setMap(map);
    }
  </script>
</body>
</html>

All your custom 3D overlays should go inside overlay.onAdd and be positioned in overlay.onDraw using transformer.fromLatLngAltitude

thanks for your answer
I want to create web based experience

as i’m working with google ai studio Build tool - I probably will be able to work in that enviorment only and not out of the google ai studio platform

i manage to get this view now. i’m looking for satellite 3d view so i can build grid on top as i’ve posted in the beginning of this thread

1 Like

:waving_hand: Status report? Any luck on the satellite Image?

no luck unfortunately - if you manage to create an app in google ai studio with such implementation that would be great.
i tried to generate a web application based on your former recommendation - that didnt work

Alright :+1: I knew it was a long shot. I had to get some sleep been awake for 2 days lol but we will give it another shot today. Where did it fail at? What worked and what did not? If you could give Gemini all your progress and code snips a get it to make summary with key points we can get this going without starting from scratch. Thanks for letting me know though.:vulcan_salute: