Generate and add a missing icon to the map
This example uses addLayer
to add a layer to a style
, but it references an image that does not exist in the style's sprite
or list of available images. Since the image is missing, the property that references the image throws a styleimagemissing
event.
This example uses that styleimagemissing
event to detect the missing image, then it generates a new image and adds that image to the map style with addImage
within the event listener callback to make sure that an icon is rendered even if the referenced image is missing.
<!DOCTYPE html><html><head><meta charset="utf-8" /><title>Generate and add a missing icon to the map</title><meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" /><script src="https://cdn.ndrive.com/nmapsgl/v.1.6.8/nmaps-gl.js"></script><link href="https://cdn.ndrive.com/nmapsgl/v.1.6.8/nmaps-gl.css" rel="stylesheet" /><style> body { margin: 0; padding: 0; } #map { position: absolute; top: 0; bottom: 0; width: 100%; }</style></head><body><div id="map"></div> <script> // TO MAKE THE MAP APPEAR YOU MUST ADD YOUR ACCESS TOKEN nmapsgl.accessToken = '<your access token here>'; const map = new nmapsgl.Map({container: 'map',style: 'Streets'}); map.on('styleimagemissing', (e) => {const id = e.id; // id of the missing image // check if this missing icon is one this function can generateconst prefix = 'square-rgb-';if (id.indexOf(prefix) !== 0) return; // extract the color from the idconst rgb = id.replace(prefix, '').split(',').map(Number); const width = 64; // The image will be 64 pixels squareconst bytesPerPixel = 4; // Each pixel is represented by 4 bytes: red, green, blue, and alpha.const data = new Uint8Array(width * width * bytesPerPixel); for (let x = 0; x < width; x++) {for (let y = 0; y < width; y++) {const offset = (y * width + x) * bytesPerPixel;data[offset + 0] = rgb[0]; // reddata[offset + 1] = rgb[1]; // greendata[offset + 2] = rgb[2]; // bluedata[offset + 3] = 255; // alpha}} map.addImage(id, { width: width, height: width, data: data });}); map.on('load', () => {map.addSource('points', {'type': 'geojson','data': {'type': 'FeatureCollection','features': [{'type': 'Feature','geometry': {'type': 'Point','coordinates': [0, 0]},'properties': {'color': '255,0,0'}},{'type': 'Feature','geometry': {'type': 'Point','coordinates': [50, 0]},'properties': {'color': '255,209,28'}},{'type': 'Feature','geometry': {'type': 'Point','coordinates': [-50, 0]},'properties': {'color': '242,127,32'}}]}}); map.addLayer({'id': 'points','type': 'symbol','source': 'points','layout': {'icon-image': ['concat', 'square-rgb-', ['get', 'color']]}});});</script> </body></html>