【问题标题】:Changing style of map elements dynamically动态更改地图元素的样式
【发布时间】:2019-03-15 18:22:03
【问题描述】:

我正在尝试即时更改许多地图元素的样式,但没有成功。我所说的动态是指从计算的颜色动态更改地图元素的颜色,例如水体。使用 Tangram,但如果有更好的解决方案,则对其他引擎开放。由于 Tangram 使用 YAML 文件来设置各种元素的样式,因此我在场景 (YAML) 文件中使用内联 Javascript。换句话说,我不想给它一个固定的颜色,而是想计算颜色(从图像中)。而不是这个:

 water:
    draw:
        polygons:
            color: "blue"

我正在按照这些思路做一些事情(因为我使用的是 Vue 路由器,所以更加复杂):

 water:
    draw:
        polygons:
            color: function() { return this.colors[0]; }

computedColorsmixing 中计算,然后广播到适当的路由:

var colorize = {

    data: function () {
        return {
            computedColors: []
        };
    },

    created: function () {
        this.getColors();
    },

    methods: {
        getColors: function () {
            ...
            self.computedColors = [
              ...
            ];
          self.$broadcast('parent-colors', self.computedColors);
          ...
        };
    };
}

路线如下:

router.map({
'/map': {

    name: 'map',

    component: Vue.extend({

        template: '#map',

        mixins: [colorize],

        data: function () {
            return {
                colors: []
            };
        },

        events: {
            'parent-colors': function (computedColors) {
                this.colors = computedColors;
            }
        },
    ready: {
        var map = L.map('map');
        var layer = Tangram.leafletLayer({
           scene: './tiles/scene.yaml'
        });
        layer.addTo(map);
        map.setView([40.70531887544228, -74.00976419448853], 15);
    }
});

感谢任何关于我可能做错的提示。


更新

我遇到了各种各样的错误。它与七巧板有关,但不太能够弄清楚它到底是什么。似乎是解析 YAML 文件的问题。如果我在scene.yaml 中更改此设置:

 water:
    draw:
        polygons:
            color: function() { return this.colors[0]; }

有了这个:

 water:
    draw:
        polygons:
            color: function() { return this.color1; }

我没有得到任何错误,但不幸的是水团仍然没有被分配任何颜色。

当然,我也必须在地图路线实例中更改这些行:

 data: function () {
            return {
                color1: ''
            };
        },
 ...

 events: {
     'parent-colors': function (computedColors) {
         this.color1 = computedColors[0];
     }
 }

【问题讨论】:

    标签: javascript vue.js leaflet vue-router tangram


    【解决方案1】:

    以下内容并未针对动态设置七巧板地图样式的具体问题提供解决方案(Yaml 似乎不容易允许),但它部分回答了如何动态设置地图矢量样式的问题。它实现了插件Leaflet.VectorGrid 并通过vectorTileLayerStyles 方法以编程方式将属性分配给层(在下面的示例中使用color: self.colors[6] 完成)。

            L.vectorGrid.slicer(countries, {
            rendererFactory: L.svg.tile,
            vectorTileLayerStyles: {
                sliced: function() {
                    return {
                    stroke: true,
                    color: self.colors[6],
                    weight: 0.5,
                    };
                }
            },
            }).addTo(map);
    

    变量countries 实际上只是一个GeoJson 加上var countries =,大致如下:

    var countries = {
        "type": "FeatureCollection",
        "features": [
            { "type": "Feature"
            (...)
            }
        ]
    };
    

    这是一个简单的解决方案,它可以完美地处理少量数据,但由于它是一个客户端解决方案,因此在处理更大的数据集时对浏览器的负担很重。不过,对于那些可能正在寻找一种简单的方法来为简化的世界地图或有限的地图区域设置样式的人来说,它可能会很有用。


    更新

    更高效的解决方案是使用磁贴服务器。下面的示例实现了t-rex,在rendererFactory 选项中使用画布渲染器L.canvas.tile 而不是L.svg.tileprotobuf

      var lines = "http://127.0.0.1:6767/lines/{z}/{x}/{y}.pbf";
      var multilinestrings = "http://127.0.0.1:6767/multilinestrings/{z}/{x}/{y}.pbf";
      var multipolygons = "http://127.0.0.1:6767/multipolygons/{z}/{x}/{y}.pbf";
    
      var vectorTileStyling = {
          lines: {
              weight: .8,
              fillColor: this.colors[1],
              color: this.colors[1],
              fillOpacity: .8,
              opacity: .8
          },
          multilinestrings: {
              weight: .8,
              fillColor: this.colors[2],
              color: this.colors[2],
              fillOpacity: .8,
              opacity: .8
          },
          multipolygons: {
              fill: true,
              weight: .8,
              fillColor: this.colors[3],
              color: this.colors[3],
              fillOpacity: .8,
              opacity: .8,
          }
      };
    
      var externalVectorTileOptions = {
          rendererFactory: L.canvas.tile,
          vectorTileLayerStyles: vectorTileStyling,
          maxZoom: 16,
          minZoom: 14
      };
      L.vectorGrid.protobuf(lines, externalVectorTileOptions).addTo(map);
      L.vectorGrid.protobuf(multilinestrings, externalVectorTileOptions).addTo(map);
      L.vectorGrid.protobuf(multipolygons, externalVectorTileOptions).addTo(map);
    

    【讨论】:

      猜你喜欢
      • 2013-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-29
      • 2021-10-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多