Draw a simple arrow in mapbox from origin to destination

Hello, I would like to know if it is possible to draw a simple arrow from origin to destination using mapbox. Thanks

Hey @jose!

It looks like this might actually be pretty tough with MapBox :sweat: I'm not finding much on drawing arrows though I might be missing something, curious to know what others have to say as well. The closest I've found so far is manually drawing the arrows with something like what's mentioned here.

Grabbing that example and making some minor tweaks gets it working in Retool:

Code for the js query:

const sourceDestinationPairs = [
  [
    ["-122.4194", "37.7949"],
    ["-122.4794","37.7749"],
  ],
];

function rotate(a, theta) {
  return [
    a[0] * Math.cos(theta) - a[1] * Math.sin(theta),
    a[0] * Math.sin(theta) + a[1] * Math.cos(theta),
  ];
}

function createArrow(a, b) {
  // a: source point
  // b: destination point
  var angle = Math.atan2(a[1] - b[1], a[0] - b[0]);
  var v = [b[0] - a[0], b[1] - a[1]]; // get direction vector
  var m = Math.sqrt(Math.pow(v[0], 2) + Math.pow(v[1], 2)); // module
  var u = [v[0] / m, v[1] / m]; // get unitary vector in the direction
  var k = 0; // how far to place the arrow end
  var newb = [b[0] - u[0] * k, b[1] - u[1] * k]; // place the arrow end a bit before the destination
  var s1 = rotate([0.01, 0.005], angle); // "sides" of the arrow. Applied to a base vector in left direction <--, and rotated to match the correct angle
  var s2 = rotate([0.01, -0.005], angle);
  return [
    a,
    newb,
    [newb[0] + s1[0], newb[1] + s1[1]],
    newb,
    [newb[0] + s2[0], newb[1] + s2[1]],
  ];
}

//...
console.log(sourceDestinationPairs);
var arrows = sourceDestinationPairs.map((x) => createArrow(x[0], x[1]));

var style = {
  type: "line",
  layout: {
    "line-cap": "round",
    },
    paint: {
      "line-width": 2,
    }
};

var source = {
  type: "FeatureCollection",
  features: [
    {
      type: "Feature",
      geometry: {
        coordinates: arrows,
        type: "MultiLineString",
      },
    },
  ],
};

return { style, source };

But it's still pretty rough, could that be something like what you're looking for?