Mapnik: SVG as a badge

I want to make an SVG image that I can use as a “badge”: It lays on top of another icon, and is smalller (<25%). The idea s to use this badge to mark LGBTQ friendly What I did was to create a 16x16px SVG and put the LGBTQ flag on the bottom right corner:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
   width="16" height="16" viewBox="0 0 16 16" version="1.1" id="svg1" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
  <defs id="defs1" />
  <g id="layer1">
    <rect style="fill:#ff0000" id="rect1" width="2" height="6" x="14" y="10" />
    <rect style="fill:#ff6600" id="rect2" width="2" height="6" x="12" y="10" />
    <rect style="fill:#ffff00" id="rect3" width="2" height="6" x="10" y="10" />
    <rect style="fill:#008000" id="rect4" width="2" height="6" x="8" y="10" />
    <rect style="fill:#0000ff" id="rect5" width="2" height="6" x="6" y="10" />
    <rect style="fill:#800080" id="rect6" width="2" height="6" x="4" y="10" />
  </g>
</svg>

Then this code added to roughly openstreetmap-carto’s #amenity-points layer:

  [lgbtq != null] {
    lgbtq/marker-file: url('symbols/local/lgbtq_overlay.svg');
    lgbtq/marker-allow-overlap: true;
  }

(assuming the right field is in the project.mml).

But when I render this with kosmtik (which internally uses carto and mapnik), the ‘badge’ is drawn right in the middle of the icon is covering:

image

I’m pretty sure I’m doing something wrong in the SVG, but I have no idea what. Any hints?

Just a totally wild guess with no prior subject knowledge.

Could it be that empty space is ignored and the icon is effectively cropped to the area that actually has graphics ?

Yes, that describes exactly what’s happening, but I need to know why or at least how to fix it. Thanks for answering.

Hey there,

upfront: I am not familiar with Mapnik. From a technical POV your SVG looks fine and shouldn’t have these issues.

I did, however, have to fight similar stuff in other software and have learned a hack for this: Try adding a transparent rectangle taking the whole space of an SVG. Something like:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
   width="16" height="16" viewBox="0 0 16 16" version="1.1" id="svg1" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
  <defs id="defs1" />
  <rect width="16" height="16" opacity="0" />
  <g id="layer1">
    <rect style="fill:#ff0000" id="rect1" width="2" height="6" x="14" y="10" />
    <rect style="fill:#ff6600" id="rect2" width="2" height="6" x="12" y="10" />
    <rect style="fill:#ffff00" id="rect3" width="2" height="6" x="10" y="10" />
    <rect style="fill:#008000" id="rect4" width="2" height="6" x="8" y="10" />
    <rect style="fill:#0000ff" id="rect5" width="2" height="6" x="6" y="10" />
    <rect style="fill:#800080" id="rect6" width="2" height="6" x="4" y="10" />
  </g>
</svg>

Maybe the SVG processor trims the SVG, and the invisible rectangle could be what stops it :) If it doesn’t work, try also with fill="transparent", fill-opacity="0", fill="#00000000", etc.

1 Like

I hate that you’re right:

image

\o/

2 Likes