title: MapBox GL JS Setup Sprites for Icon Properties
body: <p>I am having difficulty wrapping my head around MapBox GL.  I am coming from a Leaflet background, and am finding some of the abstractions hard to understand.  </p>
  
  <p>I work with a lot of GPS trip log data, and need to do things like display a fragment of a trip, hilight a section of it in a color, put markers on it with custom pins.  Another common function is to mark all units on a map with pins that differ by some status. eg: Last Reported, Fuel Level, etc.</p>
  
  <p>To create markers, I currently have a helper objectthat spits out some js.</p>
  
  <pre class="lang-c# prettyprint-override"><code>public string EmitJs()
  {
      Debug.WriteLine("Emit Marker");
      StringBuilder sb = new StringBuilder();
      sb.AppendFormat("var container{0} = document.createElement('div');", UniqueId).AppendLine();
      sb.AppendFormat("container{0}.className = '{1}';", UniqueId, ContainerCss).AppendLine();
      sb.AppendFormat("var popup{0} = new mapboxgl.Popup({{ offset: 25 }}).setHTML(", UniqueId).AppendLine(); // escape { } with {{ }} in String.Format
      sb.AppendFormat("    \'{0}\'", Point.Label).AppendLine();
      sb.AppendLine(");");
      sb.AppendFormat("var marker{0} = new mapboxgl.Marker(container{1}, {{", UniqueId, UniqueId).AppendLine();
      sb.AppendLine("    anchor: 'bottom'");
      sb.AppendLine("})");
      sb.AppendFormat("  .setLngLat({0})", Point.EmitForMapBox()).AppendLine();
      sb.AppendFormat("  .setPopup(popup{0})", UniqueId).AppendLine();
      sb.AppendLine("  .addTo(map);");
      sb.AppendLine();
  
      return sb.ToString();
  }
  </code></pre>
  
  <p>this returns: </p>
  
  <pre class="lang-js prettyprint-override"><code>var container5 = document.createElement('div');
  container5.className = 'marker marker-pu-green';
  var popup5 = new mapboxgl.Popup({ offset: 25 }).setHTML(
      '&lt;p&gt;&lt;b&gt;Name:&lt;/b&gt; 1310 PU2003&lt;br /&gt;&lt;b&gt;Last Reported:&lt;/b&gt; 25/03/2020 11:16:35&lt;br /&gt;&lt;b&gt;Last Status:&lt;/b&gt; Operating&lt;/p&gt;'
  );
  var marker5 = new mapboxgl.Marker(container5, {
      anchor: 'bottom'
  })
    .setLngLat([151.047211,-32.537003])
    .setPopup(popup5)
    .addTo(map);
  </code></pre>
  
  <p>This lets me display images overlaid on a map, governed by CSS.  This is fairly straightforward.</p>
  
  <p>The GeoJson <code>FeatureCollection</code>, contains <code>Feature's</code> that represent individual markers.  I can see that the icon properties in the <code>Layer</code> object are meant to represent named values in some spritesheet, but damned If I can figure where this is, and how to upload to it.  I've been all thru Studio, and its documentation.  It seems to refer to to a <code>'sprites': 'path to file'</code> json property that you can't actually set or upload.</p>
  
  <p>In addition, it wants the sprites to be in SVG format., despite casting them back to raster as PNG.  Thats a different question, but I need to convert a bunch of PNG's to SVG format as a result, if I ever get this working.</p>
  
  <p><strong>The Question</strong></p>
  
  <p>How do I add custom sprites to my MapBox style so I can reference them in  GeoJson icon properties.</p>
  
  <p>** Edit 27 Mar 202 **</p>
  
  <p>The following is cut from the page.  The polylines are not included (they work well), just the lines to try an make a symbol layer work.  The image paths are local to my dev environment and are valid.  They would be rewritten when moved to prod.</p>
  
  <pre><code>&lt;script id="mapScript" type="text/javascript"&gt;
  var baseUrl = '/';
  mapboxgl.accessToken = '[snip]';
  var map = new mapboxgl.Map({
      container: 'map',
      style: 'mapbox://styles/fleetlogixmaps/ck6r4knm10smq1irxvnvfmq1b',
      center: [148.381332397461,-21.4777641296387],
      setMinZoom: 13,
      setMaxZoom: 18,
      zoom: 15,
  });
  
  
  
  map.loadImage('http://localhost:7933/Images/pin_path_start_128x128.png', function(error, image) {
      if (error) throw error;
      map.addImage('pathStart', image);
  });
  
  map.loadImage('http://localhost:7933/Images/pin_path_end_128x128.png', function(error, image) {
      if (error) throw error;
      map.addImage('pathEnd', image);
  });
  
  map.loadImage('http://localhost:7933/Images/pin_event_start_128x128.png', function(error, image) {
      if (error) throw error;
      map.addImage('eventStart', image);
  });
  
  map.loadImage('http://localhost:7933/Images/pin_event_end_128x128.png', function(error, image) {
      if (error) throw error;
      map.addImage('eventEnd', image);
  });
  
  var markers = {
      'type': 'FeatureCollection',
      'features': [
          {
              'type': 'Feature',
              'geometry': {
                  'type': 'Point',
                  'coordinates': 
                      [148.370483398438,-21.4804000854492],
                  'properties': {
                      'title': 'Path Start',
                      'icon': 'pathStart'
                  }
              }
          },
  
          {
              'type': 'Feature',
              'geometry': {
                  'type': 'Point',
                  'coordinates': 
                      [148.381332397461,-21.4777641296387],
                  'properties': {
                      'title': 'Event Start',
                      'icon': 'eventStart'
                  }
              }
          },
  
          {
              'type': 'Feature',
              'geometry': {
                  'type': 'Point',
                  'coordinates': 
                      [148.385375976563,-21.4819965362549],
                  'properties': {
                      'title': 'Event End',
                      'icon': 'eventEnd'
                  }
              }
          },
  
          {
              'type': 'Feature',
              'geometry': {
                  'type': 'Point',
                  'coordinates': 
                      [148.393402099609,-21.4885864257813],
                  'properties': {
                      'title': 'Path End',
                      'icon': 'pathEnd'
                  }
              }
          }
  
      ]
  };
  
  map.on('load', function() {
      map.addLayer({
          'id': 'markers',
          'source': 'markerSrc',
          'type': 'symbol',
          'layout': {
              'icon-image': ['get', 'icon'],
              'icon-size': 0.25,
          },
  
  
      });
  
  });
  
  &lt;/script&gt;
  </code></pre>