How to apply a pattern fill style to a multipolygon that returns multiple styles

江枫思渺然 提交于 2020-02-06 08:30:48

问题


CONTEXT

I have a vector composed of multi polygons, each one of these have a unique class and I set a style related to it. I currently doing this way:

let multiPolyVector = new VectorLayer({
    source: new VectorSource ({
        format: new GeoJSON({dataProjection: 'EPSG:31982'}),
        url: 'assets/geojson/randomVector.geojson'
    }),
    style: (feature) => {
        let class = feature.get("CLASS");
        switch(class) {
            case "CLASS1":
                return this.styleArea('rgba(240, 240, 240, 1)'); // 
            break;
            case "CLASS2":
                return this.styleArea('rgba(115, 115, 240, 1)'); 
            break;
            case "CLASS3":
                return this.styleArea('rgba(168, 168, 0, 1)'); // 
            break;
            case "CLASS4":
                return this.stylePoint('rgba(255, 255, 115, 1)'); // 
            break;
        }
    }
});

The styleArea() is a function that returns an OpenLayers style:

styleArea(insideColor:string, exteriorColor:string=insideColor, exteriorWidth=2){
    let area = new Style({
        stroke: new Stroke({
            color: exteriorColor,
            width: exteriorWidth
        }),
            fill: new Fill({
            color: insideColor
        })
    });
    return area;
}

PROBLEM

Now I trying to create a function that returns an OL's style, but this time as a pattern image. After the help in this question made by myself I was able to apply the pattern style to a vector, but now I need to apply in a multi polygon vector. If I try the same way as before, all the other styles are rewrited. I tried different solutions and some of them generate the error:

TypeError: "style.getImage is not a function"

which I think is because the image isn't load yet when it is applied to the style. I believe that if I just declare the vector, then modify the style based on the filtered classes the problem can be solved (don't figured out how to yet), but I really want to return the fill partern as an OL style from a function, so that I can use later on other vectors.

  • Ionic version: 5.4.9
  • OL version: 6.1.1

My latest attempt:

stylePattern(pattern:string) {
    console.log("Function Fired");
    let patternSrc = "assets/images/patterns/" + pattern; // The pattern passed is the name of the PNG file
    let ctx = document.createElement('canvas').getContext('2d');
    let image = new Image();
    let createdPattern = ctx.createPattern(image, 'repeat');

    image.onload = () => {
        return new Style({
            fill: new Fill({
                color: createdPattern
            })
        });
    };
    image.src = patternSrc;             
}

This way I don't receive any errors and I can see the pattern image loaded in Dev Tools, but it wasn't applied to the vector style.


回答1:


The style function must return the style, not the onload function. Due to the asynchronous loading you will need a style cache solution similar to this question Scaling the icon-image size to an absolute value You might also want to pass the feature to your stylePattern function to force a rerender when the pattern is set, so the function might look something like this

let styleCache = {};

stylePattern(pattern:string, feature) {
    console.log("Function Fired");
    let style = styleCache[pattern];
    if (!style) {
      let ctx = document.createElement('canvas').getContext('2d');
      let image = new Image();
      style = new Style({
          fill: new Fill({
            color: 'transparent'
          })
        });
      styleCache[pattern] = style;
      image.onload = () => {
        let createdPattern = ctx.createPattern(image, 'repeat');
        style.getFill().setColor(createdPattern);
        feature.changed();  // force a refresh or just wait until next render?
      }
      let patternSrc = "assets/images/patterns/" + pattern; // The pattern passed is the name of the PNG file
      image.src = patternSrc;
    }
    return style;
}


来源:https://stackoverflow.com/questions/59274588/how-to-apply-a-pattern-fill-style-to-a-multipolygon-that-returns-multiple-styles

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!