0
votes

I have a series of dynamically generated SVG icons to be used as markers on a Leaflet map.

Icons take the r number and insert it into the image; this works perfectly when the icon is directly referenced by the browser, however, when the icon is placed within the Leaflet system, the icon background image does not display; but I can't find why this is so:

SVG:

/***
 * Create an SVG file using the Bronze image and apply a text as given by PHP GET clause.
 ***/
$rank = (int)$_GET['r'];
if($rank < 1 ) {
    $rank = null;
}
header("content-type: image/svg+xml");
?>
<?xml version='1.0' encoding='utf-8'?>
<svg  version='1.1' baseProfile='full' xmlns='http://www.w3.org/2000/svg' xmlns:svg='http://www.w3.org/2000/svg'
xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 20 25' xml:space='preserve' height='25' width='20'>
<image xlink:href='https://domain.co.uk/images/map_icons/bronze5_20.png' x='0' y='0' width='20' height='25' />
<text id='svgtext' x='50%' y='40%' dominant-baseline='middle' text-anchor='middle' fill='black' font-size='11px'><?php print $rank;?></text>
</svg>

Leaflet (v1.6 current ):

 var Brnz4 = L.icon({
            iconUrl: '/images/map_icons/bronze.php?r=4',
            iconSize:     [20, 25], // size of the icon
            iconAnchor:   [0, 25], // point of the icon which will correspond to marker's location
            popupAnchor:  [0, -20] // point from which the popup should open relative to the iconAnchor
        });

And

L.marker([56.224800000000000,-2.703890000000000], {icon:Brnz4} ).addTo(map)

But what actually displays is simply the text number (4) without the background image.

The background image loads ok when directly called.
The SVG (PHP) loads correctly when directly called by the browser.
The text displays in the correct position which implies the SVG is being read.

What have I tried?

  • Added various headers to the <svg>/<xml> tags as displayed above (such as viewbox, etc.) .
  • absolute URLs
  • Read this post
  • used single ' and double" quotes in the SVG incase XML was quote-type specific.

Images:

enter image description here
How the marker looks on the Leaflet Map.

enter image description here
How the leaflet appears in the browser Inspector.

enter image description here
How the marker appears with the direct URL in the browser. This should be how it appears on the map.

It appears that somehow via Leaflet the SVG background image is not being loaded. Why?

2
Have you checked whether there's a network request for https://domain.co.uk/images/map_icons/bronze5_20.png? I'm not sure how raster images embedded in SVG images should work in this particular case.IvanSanchez
@IvanSanchez after checking, no there appears to be no reference to the external PNG file.Martin

2 Answers

1
votes

With following code i have plotted SVG icons on leaflet map. In SVG code you can put your number.

var map = L.map('map', {
    center: [18.520, 73.856],
    zoom: 3,
});

// Create a Tile Layer and add it to the map
var tiles = new L.tileLayer('https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png').addTo(map);
var iconSVG='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="37" viewBox="0 0 234 366.52"> <defs><style>.c{fill:#fff;font-size:120px;font-weight: bold;}</style></defs><g transform="translate(-1206 -293)"><path style="fill:#3b9906!important;" d="M117,366.52c-7.256-61.169-34.171-117.764-76.2-160.731a117,117,0,1,1,152.4-.005c-42.023,42.97-68.945,99.57-76.2,160.736Z" transform="translate(1206 293)"></path><text class="c" transform="translate(1288 460)"><tspan x="0" y="0">9</tspan></text></g></svg>';
 L.marker([18.520, 73.856], {
                        icon: L.divIcon({
                            html: iconSVG,
                            className: ''
                        })
                    }).addTo(map)
         .bindPopup('I am SVG Icon')
         .openPopup();
#map {
  width: 500px;
  height: 400px;
}
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>


<div id="map"></div>

Hope this will help you.

0
votes

After no progress in solving this issue; I looked at alternative calls, and made an adjustment of importing the external image file as a base64 data block rather than an external file reference.

<image xlink:href='data:image/png;base64,iVBOIGlkPSJ...etc, etc....IyMDRUgg==' x='0px' y='0px' width='20px' height='25px' />

This works.