如何将图案填充样式应用于返回多种样式的多面 [英] How to apply a pattern fill style to a multipolygon that returns multiple styles

查看:108
本文介绍了如何将图案填充样式应用于返回多种样式的多面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

上下文

我有一个由多个多边形组成的矢量,每个多边形都有一个唯一的类,并且我设置了与之相关的样式.我目前正在这样做:

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;
        }
    }
});

styleArea()是返回OpenLayers样式的函数:

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;
}

问题

现在,我尝试创建一个返回OL样式的函数,但是这次将其作为图案图像.在中的帮助之后这个问题由我自己提出,可以将图案样式应用于矢量,但是现在我需要在多多边形矢量中应用.如果我尝试与以前相同的方式,则所有其他样式都将被重写.我尝试了不同的解决方案,其中一些会产生错误:

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不是函数"

TypeError: "style.getImage is not a function"

我认为这是因为将图像应用于样式后尚未加载该图像.我相信,如果我只声明向量,然后根据过滤后的类修改样式,就可以解决问题(尚不知道如何解决),但是我真的想将填充形式作为OL样式从函数,以便以后可以在其他向量上使用.

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.

  • 离子版本: 5.4.9
  • OL版本: 6.1.1
  • Ionic version: 5.4.9
  • OL version: 6.1.1

我的最新尝试:

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;             
}

这样,我没有收到任何错误,并且可以看到在Dev Tools中加载的图案图像,但是它没有应用于矢量样式.

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.

推荐答案

样式函数必须返回样式,而不是onload函数.由于异步加载,您将需要类似于此问题的样式缓存解决方案

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;
}

这篇关于如何将图案填充样式应用于返回多种样式的多面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆