Динамическое изменение стиля элементов карты - PullRequest
0 голосов
/ 10 октября 2018

Я пытаюсь изменить стиль нескольких элементов карты на лету, но безуспешно.Под «на лету» я имею в виду изменение цвета элемента карты, например, массы воды, динамически от вычисленного цвета.Используя Tangram, но открывайте другие движки, если есть лучшее решение.Так как Tangram использует файл YAML для стилизации различных элементов, я использую встроенный файл Javascript на сцене (YAML).Другими словами, вместо того, чтобы придать ему фиксированный цвет, я хочу вычислить цвет (из изображения).Вместо этого:

 water:
    draw:
        polygons:
            color: "blue"

Я делаю что-то в этом духе (еще сложнее, потому что я использую Vue Router):

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

computedColors вычисляется в mixing, затем транслируется на соответствующий маршрут:

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

Любые намеки на то, что я могу делать неправильно, оценены.


ОБНОВЛЕНИЕ

Я получаю ошибку типа.Это связано с Tangram, но не совсем в состоянии понять, что это такое.Кажется, проблема с разбором файла 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];
     }
 }

1 Ответ

0 голосов
/ 22 октября 2018

Следующее не предлагает решения конкретной проблемы стилизации карты Tangram на лету (что, кажется, 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 с рендером Canvas L.canvas.tile в опции rendererFactory вместо L.svg.tile и protobuf:

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