1

I have a case in which I should display icons for locations on the map. But, it seems like OpenLayers has issues accessing page's Assets folder. Or there's another issue I'm not aware of, because I can't see the icons on the map.

I'm using this code to set the Icon in the style function:

export interface FacilityIcons {
  [key: number]: string
}
/* After initializing in a different service it looks like this:
{
  1001: 'iconOne.svg',
  1002: 'iconTwo.svg',
  // ...
}
*/

export const getFacilityLocationStyle =
  (facilityIcons: FacilityIcons): StyleFunction =>
  (feature: FeatureLike, resolution: number): Style | Style[] => {
    const { subtype } = feature.getProperties();
    const icon = facilityIcons[subtype];
    // return icon when it matches subtype
    // subtype === 1001 => iconOne.svg

    return new Style({
      image: new Icon({
        src: `./assets/icons/facilities/${icon}`,
        crossOrigin: '*'
        // I tried also with size, scale, color but without effect
        // Weirdly enough, when I try this URL, it works
        // src: 'https://openlayers.org/en/v3.20.1/examples/data/icon.png',
      })
    });
  };

The UI uses the assets folder on other places (toolbar) and Icons are displayed correctly. So I believe the path is correct. Console shows no error, and when checking the Network tab in Dev Tools, I can see two calls to obtain the icon with the correct name and type. And the Icon is shown when I check the Response of 304 call. Load svg icon

Any idea what I'm doing wrong? I really thought this will be a simple thing.

EDIT: SVG code

<svg id="Park_1" data-name="Park 1"
  xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
  <defs>
    <style>.cls-1{fill:#08f;}.cls-2{fill:#fff;}</style>
  </defs>
  <title>PARKING</title>
  <rect class="cls-1" width="600" height="600" rx="63.03" ry="63.03"/>
  <path class="cls-2" d="M128.36,79.09,325.43,79q67.07,0,106.62,38.86t39.59,92q0,55.05-39,94.28T326.19,343.45l-87.62,0L238.65,521l-110.08,0ZM238.48,160l.05,102.49,51.24,0q68.64,0,68.62-51.28,0-28.78-18.36-40T277.39,160Z"/>
</svg>
9
  • 1
    304 suggests the image is cached so it could be a problem with the SVG, e.g. to be drawn to canvas it must width and height attributes.
    – Mike
    Commented Feb 8 at 13:01
  • Thanks for the suggestion, I'll try it
    – mat.hudak
    Commented Feb 8 at 13:54
  • Thanks for the hint, seems like it's Firefox issue. It works nicely in Safari
    – mat.hudak
    Commented Feb 8 at 13:57
  • Firefox will treat the image as zero size, but even if it does appear to work the results can be inconsistent (e.g. it may depend on the size of the canvas element being drawn to).
    – Mike
    Commented Feb 8 at 20:22
  • Can you provide your icon svg?
    – TomazicM
    Commented Feb 9 at 10:30

1 Answer 1

1

After some testing it looks like the only way to display icon in all browsers and have it's size under control is to set width and height attributes in SVG itself. These values can be changed when defining Icon in OL with either options width and height or with the scale option.

So if the SVG is defined as

<svg id="Park_1" data-name="Park 1" width="24" height="24"
  xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
  <defs>
    <style>.cls-1{fill:#08f;}.cls-2{fill:#fff;}</style>
  </defs>
  <title>PARKING</title>
  <rect class="cls-1" width="600" height="600" rx="63.03" ry="63.03"/>
  <path class="cls-2" d="M128.36,79.09,325.43,79q67.07,0,106.62,38.86t39.59,92q0,55.05-39,94.28T326.19,343.45l-87.62,0L238.65,521l-110.08,0ZM238.48,160l.05,102.49,51.24,0q68.64,0,68.62-51.28,0-28.78-18.36-40T277.39,160Z"/>
</svg>

then icon with the size 32x32 can be defined as:

new Icon({
  src: `./assets/icons/facilities/${icon}`,
  crossOrigin: '*',
  width: 32,
  height: 32
})

This is image from Firefox:

enter image description here

1
  • Thank you. That was a tricky one.
    – mat.hudak
    Commented Feb 12 at 5:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.