Search code examples
azure-maps

How to create multiple icons in Azure Maps symbol layer with same primary color but different secondary color using createFromTemplate function?


I'm having a Crafts array containing unique elements. (For ex ["Welder","Fitter","Painter"]). The data source contains an array of people containing uniqueId, craft and a property active being true or false. I have created two datasources one for active and another for inactive people. I have created custom icon from createFromTemplate method as below

let imageTemplates = [];
let inactiveImageTemplates = [];
let iconNamesActive = [];
let iconNamesInactive = [];
crafts.forEach((i) => {
  let iconNameActive = i + '_Active_' + 'Icon';
  let iconNameInactive = i + '_Inactive_' + 'Icon';
  iconNamesActive.push(i, iconNameActive);
  iconNamesInactive.push(i, iconNameInactive);
  let rColor = randomColor().hexString();
  imageTemplates.push(this.map.imageSprite.createFromTemplate(iconNameActive, 'marker-flat', rColor, '#00FF00')); //!Turn it to green
  inactiveImageTemplates.push(this.map.imageSprite.createFromTemplate(iconNameInactive, 'marker-flat', rColor, '#FF0000')); //!Turn it to red
});


Promise.all(imageTemplates).then(() => {
  console.log(imageTemplates);

  this.map.layers.add(
    new atlas.layer.SymbolLayer(this.beaconActiveDataSource, 'craftActiveLayer', {
      filter: ['!', ['has', 'point_count']],

      iconOptions: {
        image: [
          'match',
          ['get', 'role'],
          ...iconNamesActive,
          'marker-blue'
        ]
      }
    })
  );
});
Promise.all(inactiveImageTemplates).then(() => {
  this.map.layers.add(
    new atlas.layer.SymbolLayer(this.beaconInactiveDataSource, 'craftInactiveLayer', {
      filter: ['!', ['has', 'point_count']],
      iconOptions: {
        image: [
          'match',
          ['get', 'role'],
          ...iconNamesInactive,
          'marker-blue'
        ]
      }
    })
  );
});

However I'm getting a lot of console.log errors saying icon name already exists. And while zooming out the inactive icon is rendering over my Bubble layer that I already have in the map. I have concatenated "_active" and "inactive" to the icon names while creating the icon image templates for each craft to make it unique. What is the best way to create icon names/icons especially for the same entity but differentiate with secondary colors ? Thanks for your time.


Solution

  • I'm not able to reproduce that error. One possible thought is that you have two separate Promise.all calls, one after another. These will likely execute at about the same time and both try to add the images to the map sprite at the same time, which might be causing the issue. A couple possible things to try;

    1. Combine all your template promises into a single array and call Promise.all once, then add both layers in the callback. This will also allow you to better control which layer will be above the other. (Currently it's possible the second promise.all will complete first and add the second layer before the first one.)
    2. Put the second Promise.all code inside the callback of the first one. This is less efficient than #1, but requires little change to try.