Search code examples
javascriptmapboxtileterrain

Cannot get Mt.Everest RGB Tile Data from Mapbox (Not Found)


I have been looking to get back working on a JS Everest Flight Sim. Originally I had tried to create my own elevation mesh and tiles using DEM elevation data and mapping it to vertices Z axis.

I decided using Mapbox RGB tiles for elevation data would be a better approach. Unfortunately I can't seem to get it to work. The Omaha Nebraska doc example works but now the Mt. Everest tile.

I've brought the issue up here as well: https://github.com/mapbox/sphericalmercator/issues/43 Perhaps someone from Mapbox can offer me some insights :)

import fs from "fs";
import dotenv from "dotenv";
import fetch from "node-fetch";
import SphericalMercator from "@mapbox/sphericalmercator";

dotenv.config();

const queryMapbox = async () => {
  const merc = new SphericalMercator({
    size: 256,
  });
  const xyFromLatLong = (lat, long, merc) => {
    return merc.forward([long, lat]);
  };

  const zoom = 14;
  const long = 86.922623;
  const lat = 27.986065;
  const xyPos = xyFromLatLong(lat, long, merc);

  console.log({ xyPos });

  try {
    // Example from Docs - Omaha, Nebraska
    // const response = await fetch(
    //   `https://api.mapbox.com/v4/mapbox.terrain-rgb/14/12558/6127.pngraw?access_token=${process.env.ACCESS_TOKEN}`
    // );
    // const filename = "omaha-rgb.png"

    const response = await fetch(
      `https://api.mapbox.com/v4/mapbox.terrain-rgb/${zoom}/${xyPos[0].toFixed(0)}/${xyPos[1].toFixed(0)}.pngraw?access_token=${process.env.ACCESS_TOKEN}`
    );
    const filename = "everest-rgb.png"

    await new Promise((resolve, reject) => {
      const fileStream = fs.createWriteStream(`./data/${filename}`);
      response.body.pipe(fileStream);
      response.body.on("error", (err) => {
        reject(err);
      });
      fileStream.on("finish", function () {
        resolve();
      });
    });


    console.log({ response });
    // console.log({ res });
  } catch (err) {
    console.error(err);
  }
};

queryMapbox(); // Test

Solution

  • I think you are using the wrong library to convert lon, lat to tile x, y. The documentation mentions some libraries, including this one:

    tilebelt: a set of JavaScript utilities for requesting and working with tiles.

    Example:

    const tilebelt = require("@mapbox/tilebelt");
    
    console.log(tilebelt.pointToTile(86.922623, 27.986065, 14));
    
    // Output:
    // [ 12147, 6864, 14 ]
    

    With those x and y the URL will be something like this:

    https://api.mapbox.com/v4/mapbox.terrain-rgb/14/12147/6864.pngraw?access_token=YOUR_MAPBOX_ACCESS_TOKEN