Мое приложение openlayers 3 рисует на карте несколько объектов LineString (от нескольких десятков до 2000-3000).

При установке разных цветов для каждого сегмента LineStrings я получаю огромное снижение производительности (начиная всего с нескольких LineStrings на карте). Масштабирование и панорамирование полностью перестают отвечать, поэтому мое приложение нельзя использовать в этой форме.

Поскольку я не хочу устанавливать новую геометрию для каждого сегмента (а только изменять его цвет), я полагаю, что должен быть более эффективный способ достижения этой цели?

Вот мой код:

var styleFunction = function(feature, resolution) {

    var i = 0, geometry = feature.getGeometry();

    geometry.forEachSegment(function (start, end) {

        color = colors[i];

        styles.push(new ol.style.Style({
            geometry: new ol.geom.LineString([start, end]),
            fill: new ol.style.Fill({
                color: color
            }),
            stroke: new ol.style.Stroke({
                color: color,
                width: 2
            })
        }));

        i++;
    });

    return styles;
}

var vectorLayer = new ol.layer.Vector({
    source: vectorSource,
    style: styleFunction
});
5
Vinzz 29 Окт 2015 в 17:15

2 ответа

Лучший ответ

Поскольку мы не могли решить проблему, даже с учетом рекомендаций цауэрвейна, эту функцию на время отложили в холодильник. Теперь мы вернулись к нему со свежими идеями и фактически нашли «решение».

В вопросе я не совсем ясно дал понять, что сегменты LineString окрашены в соответствии со свойством их начальной точки. Таким образом, несколько последовательных сегментов могут иметь один и тот же цвет, если значение этого свойства не меняется между ними.

Идея состоит в том, чтобы не создавать новый стиль для каждого сегмента, а создавать новый стиль только при необходимости (при изменении цвета):

let i = 0,
    color = '#FE2EF7', //pink. should not be displayed
    previousColor = '#FE2EF7',
    lineString,
    lastCoordinate = geometry.getLastCoordinate();

geometry.forEachSegment(((start, end) => {

        color = this.getColorFromProperty(LinePoints[i].myProperty);

        //First segment
        if (lineString == null) {
            lineString = new ol.geom.LineString([start, end]);
        } else {

            //Color changes: push the current segment and start a new one
            if (color !== previousColor) {

                styles.push(new ol.style.Style({
                    geometry: lineString,
                    fill: new ol.style.Fill({
                        color: previousColor
                    }),
                    stroke: new ol.style.Stroke({
                        color: previousColor,
                        width: 2
                    })
                }));

                lineString = new ol.geom.LineString([start, end]);

            } else {
                //Color is same: continue the current segment
                lineString.appendCoordinate(end);
            }

            //Last segment
            if (end[0] === lastCoordinate[0] && end[1] === lastCoordinate[1]) {
                styles.push(new ol.style.Style({
                    geometry: lineString,
                    fill: new ol.style.Fill({
                        color: color
                    }),
                    stroke: new ol.style.Stroke({
                        color: color,
                        width: 2
                    })
                }));
            }
        }

        previousColor = color;
        i++;
    }
2
Vinzz 21 Июн 2018 в 12:46

Вот несколько вещей, которые вы можете попробовать оптимизировать:

Стиль заливки и обводки кеша

var fillStyles = colors.map(function(color, i) {
  return new ol.style.Fill({
    color: color
  })
});

var strokeStyles = colors.map(function(color, i) {
  return new ol.style.Stroke({
      color: color,
      width: 2
  })
});

Сохраните стиль для каждой функции

vectorSource.forEach(function(feature, i) {
  var geometry = feature.getGeometry();
  var styles = [];
  var i = 0;

  geometry.forEachSegment(function (start, end) {
    styles.push(new ol.style.Style({
        geometry: new ol.geom.LineString([start, end]),
        fill: fillStyles[i],
        stroke: strokeStyles[i]
    }));
    i++;
  });
  feature.setStyle(styles);
});

Отключить обновление рендеринга во время анимации и взаимодействий

var vectorLayer = new ol.layer.Vector({
    source: vectorSource,
    updateWhileAnimating: false,
    updateWhileInteracting: false
});

См. ol.layer.Vector.

Если все это не помогает, вы также можете взглянуть на ol.source.ImageVector (пример ).

5
Mario Campa 28 Окт 2018 в 21:44