David
David

Reputation: 825

Mapbox GL JS : How to add a canvas, and get data from it? (Weather Map)

I have 2 issues that seem to go hand in hand, and I am trying my best to understand them after much research.

I do not understand how to add a canvas to my map. I am sure this must be simple, but I cannot find a basic working example. I have also done research on the API : https://www.mapbox.com/mapbox-gl-js/api/#canvassource - but it does not seem to work like an image overlay does.

The API link above shows how to add a canvas source but not how to display it on the map. Am I missing where they show the example or is it just not there? (I will add an example of how an image source I use works). This is the first thing I would like to do.

In my project, I am displaying weather radar data. Once I have a canvas source working and displaying - I would like to have the data value displayed as the user hovers the mouse over the data as a tooltip following the cursor (The data is rain -I will attach an example screenshot). For each color of the canvas, I know already the exact value of the pixel (example : #63C2FF = 15.4, #469B00 = 23.4, #FDF900 = 31.5, etc) - So that is no issue.

Is this possible to do in MapBox GL JS? From what I read online, it is possible only using a canvas. There appears to be ways to get data from the image as listed in the MapBox API, but again I have no examples to look at. If I even had working code of a 10px by 10px image with only 2 colors, I could figure out the rest. I have many other things I need to do (like refreshing the image, etc) but I understand how to do all that now.

Below is working and correct code for an image overlay that I am using, and If I am right, does the canvas work in a similar way?

map.on('load', function() {
  map.addSource("source_KEWX_L2_REFLECTIVITY", {
    "type": "image",
    "url": "images/KEWX_L2_REFLECTIVITY.gif",
    "coordinates": [
      [-103.009641, 33.911],
      [-94.009641, 33.911],
      [-94.009641, 24.911],
      [-103.009641, 24.911]
    ]
  })
  map.addLayer({
    "id": "overlay_KEWX_L2_REFLECTIVITY",
    "source": "source_KEWX_L2_REFLECTIVITY",
    "type": "raster",
    "raster-opacity": 0.5,
    "layout": {
      "visibility": "none"
    },
  })
});

And lastly, the example image of how I would like to eventually get this to work:

canvas

Upvotes: 0

Views: 4678

Answers (1)

Scarysize
Scarysize

Reputation: 4281

You're right, the documentation has quite some gaps on the canvas source type. Though you can find it mentioned here: https://www.mapbox.com/mapbox-gl-js/api#canvassource

Generally you can use a canvas source like you would use a image source, this means you would also choose a raster layer to display it on the map.

Access color values

To access the color values of the canvas' content you can use the getImageData method of the context:

const context = canvas.getContext('2d');
const imageData = context.getImageData(0, 0, canvas.width, canvas.height);

You can now access the colors from the imageData.data property. This will give you a flat (1-dimensional) array of colors in RGBA order. So if you image a 4x4px image, your array will look something like this:

[
  r0, g0, b0, a0, // pixel [0, 0]
  r1, g1, b1, a1, // pixel [1, 0]
  r2, g2, b2, a2, // pixel [0, 1]
  r3, g3, b3, a3  // pixel [1, 1]
]

The values will be between 0 and 255.

Now all you have to do is capture the mousemove on the map, retrieve the lng/lat position of the cursor, transform this position into an x/y position so you can access the correct pixel in the image data.

Upvotes: 1

Related Questions