使用包含LineStrings的矢量源在OpenLayers中创建热图

时间:2019-06-26 20:50:32

标签: openlayers openlayers-3

我有兴趣在OpenLayers中创建热图,以可视化空间中某些观测的密度。我的数据以GeoJSON文件的形式出现,其中一些包含点要素,而其他则包含LineString。

我能够从包含点的GeoJSON文件创建矢量源,从而成功地可视化了来自该源的热图图层。但是,我无法按照与GeoJSON文件包含LineStrings相同的步骤来创建热图。

是否完全支持此功能?

谢谢!

1 个答案:

答案 0 :(得分:1)

热图生成仅适用于点几何的图像样式。对于具有其他几何类型的要素,可以将默认样式功能生成的样式的几何更改为要素几何的标注点(对于LineString,则为线的中点;对于Polygon,为其内点)。这是OpenLayers示例代码,已更改为在铁路网络中使用由LineString组成的GeoJSON。

  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>