1

I was trying to have a vector layer(from OL) above Open Street Map (OSM()). I wanted a wind barb layer, for which I used d3-wind-barb from npm. I couldn't use it as style though it throws HTML objects in the console.

        layers: [
      new TileLayer({
        source: new OSM(),
      }),
      new VectorLayer({
        source: vectorSource,
        style: function (feature) {
          const wind = feature.get("wind");
          
          // using d3 windbarb
          var svg = new D3WindBarb(180, 50).draw("#container");
          console.log(svg);
          
          var svg_1 =
            "data:image/svg+xml;utf8," +
            '<svg width="120" height="120" version="1.1" xmlns="http://www.w3.org/2000/svg">' +
            '<circle cx="60" cy="60" r="60"/>' +
            "</svg>";

          console.log(svg_1);
          const outVal = new Style({
            image: new Icon({
              src: svg_1,
              // src: svg,  to be used when svg is set as source 
              size: 0.1,
            }),
          });
          return outVal;
        },
      }),
    ]

In this code when I try using src inside ICON as svg it doesn't work but when I use svg_1 the SVG is shown as a layer. During the console of svg and svg_1 the types are object and string respectively, but in both cases, they contain HTML tags.

How can I solve this problem? Additionally, I would be open to considering alternative methods for displaying wind barbs in OpenLayers.

0

1 Answer 1

0

According to D3WindBarb docs (see https://ilsanchez.github.io/d3-wind-barbs/classes/d3windbarb.html#draw) your OL code to display D3WindBarb icon as vector layer style icon should look like something this:

new VectorLayer({
  source: vectorSource,
  style: function (feature) {
    const wind = feature.get("wind");
    var svg = new D3WindBarb(180, 50, {
      size: {
        height: 20,
        width: 50
      }
    }).draw();
    const outVal = new Style({
      image: new Icon({
        src: 'data:image/svg+xml;utf8,' + svg.outerHTML,
      })
    });
    return outVal;
  },
})

It turned out that the above code does not work. After a lot of experimenting it turned out that some modification of SVG element created by D3WindBarb is needed.

This is code that works:

const windBarb = new D3WindBarb(
  86, // In knots. If your data is in other units you shuld pass de correct conversionFactor
  45, // in degrees
  // All this configuration is optional. Change it  or comment it to check its effects
  {
    bar: {
      angle: 30,
      fullBarClassName: "",
      padding: 6,
      shortBarClassName: "",
      stroke: "#000",
      width: 2
    },
    circle: {
      fill: "#FFFFFF00",
      stroke: "#000",
      radius: 10,
      strokeWidth: 2,
      className: "wind-barb-zero-knots-circle"
    },
    conversionFactor: ConversionFactors.None,
    rootBarClassName: "",
    size: {
      width: 80,
      height: 40
    },
    svgId: "",
    triangle: {
      fill: "#000",
      stroke: "#000",
      padding: 6,
      className: "wind-barb-triangle"
    },
    baseCircle: {
      className: "wind-barb-base-circle",
      fill: "#000",
      radius: 5,
      stroke: "#000",
      strokeWidth: 1
    }
  }
).draw();

windBarb.setAttribute("xmlns", "http://www.w3.org/2000/svg");
windBarb.setAttribute("xmlns:svg", "http://www.w3.org/2000/svg");
windBarb.setAttribute("width", "40");
windBarb.setAttribute("height", "80");

const style = new Style({
   image: new Icon({
      opacity: 1,
     src: 'data:image/svg+xml;utf8,' + window.encodeURIComponent(windBarb.outerHTML),
    })
});

const feature = new Feature(
  new Point(olProj.fromLonLat([14.5, 46]))
);

const vectorSource = new VectorSource({
  features: [feature]
});

This is how the result looks like:

enter image description here

3
  • I tried the code but it still does not seem to work. It would be great if you have any other ideas to add wind barbs in OpenLayers. Commented Apr 30, 2023 at 15:35
  • See modified answer.
    – TomazicM
    Commented May 1, 2023 at 15:27
  • Thank You for the code, it works. Commented May 2, 2023 at 14:12

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.