enzet / map-machine

Python renderer for OpenStreetMap with custom icons intended to display as many map features as possible
MIT License
514 stars 34 forks source link

Röntgen-icons have double the size they need to have #150

Closed westnordost closed 1 year ago

westnordost commented 1 year ago

Icons generated via map-machine icons seem to output the shape twice. E.g. the SVG generated for buses.svg looks like this:

<?xml version="1.0" encoding="utf-8" ?>
<svg baseProfile="full" height="16" version="1.1" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs />
<path d="m 241.5,532 c -0.277,0 -0.5,0.223 -0.5,0.5 v 6 c 0,0.277 0.223,0.5 0.5,0.5 h 5 c 0.277,0 0.5,-0.223 0.5,-0.5 v -6 c 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 7,0 c -0.277,0 -0.5,0.223 -0.5,0.5 v 6 c 0,0.277 0.223,0.5 0.5,0.5 h 5 c 0.277,0 0.5,-0.223 0.5,-0.5 v -6 c 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m -6.5,1 h 4 v 3 h -4 z m 7,0 h 4 v 3 h -4 z m -6.5,3.77344 A 0.72727275,0.72727275 0 0 1 243.22656,537.5 0.72727275,0.72727275 0 0 1 242.5,538.22656 0.72727275,0.72727275 0 0 1 241.77344,537.5 0.72727275,0.72727275 0 0 1 242.5,536.77344 Z m 3,0 A 0.72727275,0.72727275 0 0 1 246.22656,537.5 0.72727275,0.72727275 0 0 1 245.5,538.22656 0.72727275,0.72727275 0 0 1 244.77344,537.5 0.72727275,0.72727275 0 0 1 245.5,536.77344 Z m 4,0 A 0.72727275,0.72727275 0 0 1 250.22656,537.5 0.72727275,0.72727275 0 0 1 249.5,538.22656 0.72727275,0.72727275 0 0 1 248.77344,537.5 0.72727275,0.72727275 0 0 1 249.5,536.77344 Z m 3,0 A 0.72727275,0.72727275 0 0 1 253.22656,537.5 0.72727275,0.72727275 0 0 1 252.5,538.22656 0.72727275,0.72727275 0 0 1 251.77344,537.5 0.72727275,0.72727275 0 0 1 252.5,536.77344 Z" fill="#000" transform="translate(8.0,8.0) translate(-248.0,-536.0)" />
<path d="m 241.5,532 c -0.277,0 -0.5,0.223 -0.5,0.5 v 6 c 0,0.277 0.223,0.5 0.5,0.5 h 5 c 0.277,0 0.5,-0.223 0.5,-0.5 v -6 c 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 7,0 c -0.277,0 -0.5,0.223 -0.5,0.5 v 6 c 0,0.277 0.223,0.5 0.5,0.5 h 5 c 0.277,0 0.5,-0.223 0.5,-0.5 v -6 c 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m -6.5,1 h 4 v 3 h -4 z m 7,0 h 4 v 3 h -4 z m -6.5,3.77344 A 0.72727275,0.72727275 0 0 1 243.22656,537.5 0.72727275,0.72727275 0 0 1 242.5,538.22656 0.72727275,0.72727275 0 0 1 241.77344,537.5 0.72727275,0.72727275 0 0 1 242.5,536.77344 Z m 3,0 A 0.72727275,0.72727275 0 0 1 246.22656,537.5 0.72727275,0.72727275 0 0 1 245.5,538.22656 0.72727275,0.72727275 0 0 1 244.77344,537.5 0.72727275,0.72727275 0 0 1 245.5,536.77344 Z m 4,0 A 0.72727275,0.72727275 0 0 1 250.22656,537.5 0.72727275,0.72727275 0 0 1 249.5,538.22656 0.72727275,0.72727275 0 0 1 248.77344,537.5 0.72727275,0.72727275 0 0 1 249.5,536.77344 Z m 3,0 A 0.72727275,0.72727275 0 0 1 253.22656,537.5 0.72727275,0.72727275 0 0 1 252.5,538.22656 0.72727275,0.72727275 0 0 1 251.77344,537.5 0.72727275,0.72727275 0 0 1 252.5,536.77344 Z" fill="#000" transform="translate(8.0,8.0) translate(-248.0,-536.0)" />
</svg>

As you see, it contains the same path twice.

enzet commented 1 year ago

@westnordost Sorry for the late response. Hope this issue is still relevant for you. This is actually a quite stupid bug. This first duplicate should be used for the outline for the icon and should be just dropped if outline is not needed.

This should be fixed in 825eb34191ebdfcd5a634806a39b4aa536f9d430.

However, I now realised that this duplication seems to be wrong in the first place. SVG can have definitions, so we may you this feature to store the actual path once and then use it as many times as we want by reference.

If you think, this particular duplication bug is fixed, I will close this issue and create a new one concerning definitions.

westnordost commented 1 year ago

Well, I do need these icons for the Android platform and thus need to convert them to so-called Android drawables which support a very limited subset of SVG. Definitions and linking to them is not amongst these. So for my use case, I'd need the icons in "plain" SVG, i.e. just paths with properties how to stroke or fill them. Note that you can give a path both a stroke and a fill at the same time.

enzet commented 1 year ago

@westnordost Yeah, sure. Those remarks were mostly about complex icon combinations and map generation. I have no intention of creating more complex SVG files for simple icons.

Note that you can give a path both a stroke and a fill at the same time.

No, that won't work for what I want. If you take a look at maps that Map Machine generates, icons have outlines (stroke, that goes outside, but not inside of the shape). The simplest way to create such kind of outline is to draw a shape with a stroke beneath the same shape without a stroke.

By the way, in the nearest future icons will migrate into a separate repository Röntgen. So you won't have to generate icons (unless you want some custom icon combinations). If you find more issues with icons, please report them there.

enzet commented 1 year ago

Now icons should be easily downloadable from this directory. Please check if the resulting SVG files are what you need.

I do need these icons for the Android platform

Could you please tell me where exactly and how do you use the icons? This would be crucial for my understanding of how to develop the icon set outside the Map Machine project.

westnordost commented 1 year ago

I do use these icons in the so-called shops overlay in StreetComplete. The iD presets define certain icons to be used for certain presets, and for some presets, Röntgen icons are used. These icons are displayed on the map but also in the preset-selection dialog. Overall, pretty similar to how iD displays these icons.

Android does not have SVG support but instead uses Android vector drawables which support a certain basic subset of SVG that should be completely fine for any plain vector icons. The path definition is identical to the SVG path definition which is why it is quite trivial to convert it for simple vector graphics.

For example, the temaki coffee.svg

<?xml version="1.0" encoding="UTF-8"?>
<svg 
    version="1.1"
    xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
    x="0"
    y="0"
    viewBox="0 0 15 15">
  <path d="M13.5 1C14 0.5 6.5 0 3 3.5C1 5.5 0 8.5 0 10C0 12 1 15 3 15C10 15 12.5 9.5 13.5 7.5C14.5 5.5 15 1.5 14 1.5C13.5 1.5 11 3 10 4C9 5 9 7 8 8C7 9 5.5 9 4.5 10C3.5 11 2 12.5 2 12.5C2 12.5 2.5 10 3.5 9C4.5 8 5.5 8 6.5 7C7.5 6 8 4 9 3C10 2 13 1.5 13.5 1z"/>
</svg>

looks like this when converted to Android drawable:

<vector 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="15.0dp"
    android:viewportHeight="15"
    android:viewportWidth="15"
    android:width="15.0dp">
    <path 
        android:fillColor="#000"
        android:pathData="M13.5 1C14 0.5 6.5 0 3 3.5C1 5.5 0 8.5 0 10C0 12 1 15 3 15C10 15 12.5 9.5 13.5 7.5C14.5 5.5 15 1.5 14 1.5C13.5 1.5 11 3 10 4C9 5 9 7 8 8C7 9 5.5 9 4.5 10C3.5 11 2 12.5 2 12.5C2 12.5 2.5 10 3.5 9C4.5 8 5.5 8 6.5 7C7.5 6 8 4 9 3C10 2 13 1.5 13.5 1z"/>
</vector>

To download and convert the SVG icons used by the iD presets into android vector drawables, I wrote this little download & convert script:

https://github.com/streetcomplete/StreetComplete/blob/master/buildSrc/src/main/java/DownloadAndConvertPresetIconsTask.kt

Now, this script can unfortunately not handle transform, so in the format right now, StreetComplete is not able to use Roentgen icons.

Would it be possible to "bake" the translate into the path instead?

enzet commented 1 year ago

Oh, I see. I think I can relatively easily get rid of transform for simple icons, but I feel like for combined icons it will be much harder. I've created an issue. Please track the progress there.

Please, be warned that Röntgen repository is not in a fully stable condition.

enzet commented 1 year ago

@westnordost I made changes that removes transform from SVG files. Could you please check if this works for you: icons directory on a branch.