Создание Heatmap в OpenLayers с векторным источником, содержащим LineStrings - PullRequest
0 голосов
/ 26 июня 2019

Я заинтересован в создании тепловых карт в OpenLayers для визуализации плотности определенных наблюдений в космосе. Мои данные поступают в виде файлов GeoJSON, некоторые из которых содержат точечные объекты, а другие содержат LineStrings.

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

Поддерживается ли эта функция вообще?

Спасибо!

1 Ответ

1 голос
/ 27 июня 2019

Heatmap генерирует стиль изображения, который работает только для точечной геометрии. Для объектов с другими типами геометрии геометрия стиля, сгенерированного функцией стиля по умолчанию, может быть изменена на точку метки геометрии объекта (для LineString средняя точка линии или для Polygon ее внутренняя точка). Это пример кода OpenLayers, измененный для использования GeoJSON, состоящего из LineStrings, для железнодорожной сети.

  var blur = document.getElementById('blur');
  var radius = document.getElementById('radius');

  proj4.defs('EPSG:4277', '+proj=longlat +ellps=airy +towgs84=446.448,-125.157,542.06,0.15,0.247,0.842,-20.489 +no_defs ');
  ol.proj.proj4.register(proj4);

  var vector = new ol.layer.Heatmap({
    source: new ol.source.Vector({
      url: 'https://data.glasgow.gov.uk/dataset/d4b27465-b76c-4131-a1ff-31d038b8fdd0/resource/8eadfcc3-b91e-4b1a-a275-c0f1bcd8de7d/download/railway-line.geojson',
      format: new ol.format.GeoJSON({
        dataProjection: 'EPSG:4277'
      })
    }),
    blur: parseInt(blur.value, 10),
    radius: parseInt(radius.value, 10)
  });

  var defaultStyleFunction = vector.getStyleFunction();
  vector.setStyle(function(feature, resolution) {
    var style = defaultStyleFunction(feature, resolution);
    var geom = feature.getGeometry();
    if (geom.getType() == 'LineString') {
      style[0].setGeometry(new ol.geom.Point(geom.getCoordinateAt(0.5)));
    }
    return style;
  });

  vector.getSource().on('addfeature', function(event) {
    var name = event.feature.get("IDENTIFIER");
    event.feature.set('weight', (name - 2500000000000)/200000000000);
  });

  var raster = new ol.layer.Tile({
    source: new ol.source.Stamen({
      layer: 'toner'
    })
  });

  var map = new ol.Map({
    layers: [raster, vector],
    target: 'map',
    view: new ol.View({
      center: ol.proj.transform([-4.23, 55.86], 'EPSG:4277', 'EPSG:3857'),
      zoom: 14,
    })
  });


  blur.addEventListener('input', function() {
    vector.setBlur(parseInt(blur.value, 10));
  });

  radius.addEventListener('input', function() {
    vector.setRadius(parseInt(radius.value, 10));
  });
html, body, .map {
    margin: 0;
    padding: 0;
    width: 100%;
    height: 90%;
}
<link href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" rel="stylesheet" />
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.5.0/proj4.js"></script>
<div id="map" class="map"></div>
<form>
  <label>radius size</label>
  <input id="radius" type="range" min="1" max="50" step="1" value="25"/>
  <label>blur size</label>
  <input id="blur" type="range" min="1" max="50" step="1" value="15"/>
</form>
...